C# 一对一实体或零对一实体框架代码优先FluentApi 我需要创建fluentapi一对一或零对一引用,并在这两个实体上都有导航属性
EntityTwo应该包含存储外键的简单属性(EntityOneId)C# 一对一实体或零对一实体框架代码优先FluentApi 我需要创建fluentapi一对一或零对一引用,并在这两个实体上都有导航属性,c#,entity-framework,ef-code-first,ef-fluent-api,C#,Entity Framework,Ef Code First,Ef Fluent Api,EntityTwo应该包含存储外键的简单属性(EntityOneId) 公共类EntityOne { 公共int Id{get;set;} public EntityTwo EntityTwo{get;set;} } 公共类实体2 { 公共int Id{get;set;} public int EntityOneId{get;set;} 公共EntityOne EntityOne{get;set;} } 公共类MyDbContext:DbContext { 模型创建时受保护的覆盖无效(DbMod
公共类EntityOne
{
公共int Id{get;set;}
public EntityTwo EntityTwo{get;set;}
}
公共类实体2
{
公共int Id{get;set;}
public int EntityOneId{get;set;}
公共EntityOne EntityOne{get;set;}
}
公共类MyDbContext:DbContext
{
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
基于模型创建(modelBuilder);
//一些代码被删除了
modelBuilder.Entity()
.has可选(entity=>entity.EntityTwo)
.WithRequired();
modelBuilder.Entity()
.HasRequired(entity=>entity.EntityOne)
.有很多
.HasForeignKey(实体=>entity.EntityOneId)
.WillCascadeOnDelete(假);
}
}
更复杂的情况:
public class EntityOne
{
public int Id { get; set; }
public EntityTwo EntityTwo { get; set; }
}
public class EntityThree
{
public int Id { get; set; }
public EntityTwo EntityTwo { get; set; }
}
public class EntityTwo
{
public int Id { get; set; }
public int EntityOneId { get; set; }
public EntityOne EntityOne { get; set; }
public int EntityThreeId { get; set; }
public EntityThree EntityThree { get; set; }
}
public class MyDbContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
//some code trimmed
modelBuilder.Entity<EntityOne>()
.HasOptional(entity => entity.EntityTwo)
.WithRequired();
modelBuilder.Entity<EntityThree>()
.HasOptional(entity => entity.EntityTwo)
.WithRequired();
modelBuilder.Entity<EntityTwo>()
.HasRequired(entity => entity.EntityOne)
.WithMany()
.HasForeignKey(entity => entity.EntityOneId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<EntityTwo>()
.HasRequired(entity => entity.EntityThree)
.WithMany()
.HasForeignKey(entity => entity.EntityThreeId)
.WillCascadeOnDelete(false);
}
}
公共类EntityOne
{
公共int Id{get;set;}
public EntityTwo EntityTwo{get;set;}
}
公共类实体三
{
公共int Id{get;set;}
public EntityTwo EntityTwo{get;set;}
}
公共类实体2
{
公共int Id{get;set;}
public int EntityOneId{get;set;}
公共EntityOne EntityOne{get;set;}
公共int EntityThreeId{get;set;}
公共实体三个实体三{get;set;}
}
公共类MyDbContext:DbContext
{
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
基于模型创建(modelBuilder);
//一些代码被删除了
modelBuilder.Entity()
.has可选(entity=>entity.EntityTwo)
.WithRequired();
modelBuilder.Entity()
.has可选(entity=>entity.EntityTwo)
.WithRequired();
modelBuilder.Entity()
.HasRequired(entity=>entity.EntityOne)
.有很多
.HasForeignKey(实体=>entity.EntityOneId)
.WillCascadeOnDelete(假);
modelBuilder.Entity()
.HasRequired(entity=>entity.EntityThree)
.有很多
.HasForeignKey(实体=>entity.EntityThreeId)
.WillCascadeOnDelete(假);
}
}
在一对一关系中,一端必须是主体,另一端必须是依赖的。主端是将首先插入的端,并且可以在没有从属端的情况下存在。从属端是必须插入主体后的端,因为它具有主体的外键。在配置一对一关系时,Entity Framework要求依赖关系的主键也是外键。实现所需目标的正确方法可能是这样,但使用数据注释:
public class EntityOne
{
public int Id { get; set; }
public virtual EntityTwo EntityTwo { get; set; }
}
public class EntityTwo
{
[Key, ForeignKey("EntityOne")]
public int EntityOneId { get; set; }
public virtual EntityOne EntityOne { get; set; }
}
我建议你检查一下,你可以找到更多关于如何在EF代码中一对一关系的信息
更新:
恐怕您想要的是不可能的。您无法创建与未声明为PK的FK的一对一关系。如果要让每个实体都具有自己的
Id
an,请在这两个实体之间配置一对一的关系,然后删除EntityTwo
中的FK属性
我的建议是使用Fluent Api映射这种关系,如下所示:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<EntityTwo>()
.HasRequired(et => et.EntityOne)
.WithOptional(eo=>eo.EntityTwo);
}
我想出的处理这个问题的唯一方法是创建一个集合和一个helper属性来表示1/0边,这是公认的有点难看的。为了清晰起见,包含了数据注释
公共类EntityOne
{
[关键]
public int EntityOneId{get;set;}
public EntityTwo EntityTwo=>EntityTwoNavigation?.FirstOrDefault();
公共ICollection EntityTwoNavigation{get;set;}
}
公共类实体2
{
[关键]
public int EntityTwoId{get;set;}
public int EntityOneId{get;set;}
[外键(“EntityOneId”)]
公共EntityOne EntityOne{get;set;}
}
可能从中复制。还是我错了?为了清楚起见,你可以用这个例子。这个例子是有效的,但是它不符合我的期望。我希望EntityTwo有自己的Id,带有指向其他实体的链接(每个链接都是唯一的)Hello@OlegGochachko。不久前我更新了我的答案。您尝试过该配置吗?“您无法创建与未声明为PK的FK的一对一关系。”根据SQL,FK是候选密钥之一就足够了。
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<EntityTwo>()
.HasRequired(et => et.EntityOne)
.WithOptional(eo=>eo.EntityTwo);
}
public class EntityTwo
{
public int Id { get; set; }
// public int EntityOneId { get; set; }
[Required]
public EntityOne EntityOne { get; set; }
}