我需要创建fluentapi一对一引用,并在两个实体上都有导航属性。
EntityTwo应包含用于存储外键的简单proerty(EntityOneID)
public class EntityOne
{
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 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<EntityTwo>()
.HasRequired(entity => entity.EntityOne)
.WithMany()
.HasForeignKey(entity => entity.EntityOneId)
.WillCascadeOnDelete(false);
}
}
更复杂的场景:
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);
}
}
最佳答案
在一对一关系中,一端必须是主体,另一端必须是从属的。主体端是先插入的,没有依赖的可以存在。从属端是必须插入到主体之后的端,因为它具有主体的外键。在配置一对一关系时,实体框架要求依赖项的主键也是外键。实现您想要的目标的正确方法可能是这样,但是使用数据注释:
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; }
}
我建议你检查一下这个link,你可以先在ef代码中找到更多关于如何处理一对一关系的信息。
更新:
恐怕你想要的是不可能的,你不能和一个没有声明为pk的fk建立一对一的关系。如果希望每个实体都有自己的
Id
并在这两个实体之间配置一对一关系,则删除EntityTwo
中的fk属性。我的建议是使用fluent api映射关系,如下所示:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<EntityTwo>()
.HasRequired(et => et.EntityOne)
.WithOptional(eo=>eo.EntityTwo);
}
或者只需在作为主体的navigation属性上添加
Required
属性,例如:public class EntityTwo
{
public int Id { get; set; }
// public int EntityOneId { get; set; }
[Required]
public EntityOne EntityOne { get; set; }
}