我是在从属实体还是主体上定义两个实体之间的关系
本文关键字:实体 两个 之间 关系 主体 定义 | 更新日期: 2023-09-27 18:36:53
使用实体框架时,我对需要在哪里定义两个实体之间的关系感到困惑。我觉得每当我寻找例子时,我最终都会从两个不同的角度找到同一件事的例子——依赖→主体,以及主要→依赖。
给定以下实体:
class Foo
{
public int Id { get; set; }
public virtual ICollection<Bar> Bars { get; set; }
}
class Bar
{
public int Id { get; set; }
public Foo Foo { get; set; }
public virtual Baz { get; set; }
}
class Baz
{
public int Id { get; set; }
public Bar Bar { get; set; }
}
我们这里有几种方案。 Foo
有很多Bar
指向它。 Baz
有一个可选的外键来Bar
。 Baz
可以在没有指定Bar
的情况下存在。
我在哪里定义这些关系?我的意思是,在使用流畅的 API 时,这些关系将定义与哪个实体相关?也许为了更清楚,如果我使用流畅的 API 和 EntityTypeConfiguration
类进行绑定,这些将在哪个实体中定义?
我感到困惑的一个例子是因为我看到这样的答案说应该在具有virtual
的类中定义一对一。因此,在这些实体中,Baz
和 Bar
之间的可选一对一将是,或类似于以下内容:
modelBuilder.Entity<bar>()
.HasOptional(f => f.Baz)
.WithRequired(s => s.Bar);
我想你对virtual
关键字感到困惑。我确实尝试在您链接到的页面上找到它,但它不存在。
virtual
关键字允许实体框架重写它在后台创建并从 Bar
继承的代理实体中的该属性。然后,重写将在访问属性时对延迟加载Baz
进行数据库调用。
virtual
关键字与关系的定义无关,如果您不希望延迟加载,则不需要它。
您可以在映射时定义主体:
modelBuilder.Entity<bar>()
.HasOptional(f => f.Baz). //Baz is dependent
.WithRequired(s => s.Bar);//Bar is principal
modelBuilder.Entity<bar>()
.HasOptional(f => f.Bar). //Bar is dependent
.WithRequired(s => s.Baz);//Baz is principal
至于您的示例中Foo
和Bar
之间的其他关系,Foo
有一个Bars
集合,但Foo
只有一个Bar
所以外键继续Bar
。默认情况下,EF 将执行此操作。
依赖服务器获取引用主体密钥的外键。当它是一对一的时,该外键也是依赖项的主键,但 EF 无法确定哪个是哪个,这就是在指定错误之前出现错误的原因。
参考: http://msdn.microsoft.com/en-us/library/ee382827.aspx
当您使用类中定义的 EF 时,您已经定义了关系。EF 能够理解当您在类的集合中定义导航属性时
public virtual ICollection<Bar> Bars { get; set; }
你想要一对多的关系。
另一方面,如果将集合添加到其他类
public virtual ICollection<Foo> Foos { get; set; }
EF会明白你想要很多可能的关系
如果你在另一个类中添加一个类的实例作为属性,也会发生同样的事情,它将理解为一对一(或零对一)的关系。
如前所述,虚拟关键字与您的关系无关,它涉及懒惰,急切的加载