我是否在依赖关系或主体上定义了两个实体之间的关系?

时间:2013-10-25 02:19:16

标签: c# entity-framework

使用Entity Framework时,我对在两个实体之间定义关系的位置感到困惑。我觉得无论何时我寻找例子,我最终都会从两个不同的角度找到相同的例子 - 依赖→委托,以及委托 - 依赖。

鉴于以下实体:

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类进行绑定,那么这些实体将被定义在哪个实体中?

为什么我感到困惑的一个例子是因为我看到像this one这样的答案,说明应该在班级中使用virtual来定义一对一。因此,在这些实体中,BazBar之间的可选一对一将是或类似于:

modelBuilder.Entity<bar>()
            .HasOptional(f => f.Baz)
            .WithRequired(s => s.Bar);

2 个答案:

答案 0 :(得分:2)

我认为您对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

至于您的示例中FooBar之间的其他关系,Foo的集合为BarsFoo只有一个Bar所以外键继续Bar。 EF默认会这样做。

依赖项获取引用主体密钥的外键。如果它是一对一的,那个外键也是依赖的主键,但是EF无法解决哪个是哪个,这就是为什么在你指定错误之前就会出现错误的原因。

参考:http://msdn.microsoft.com/en-us/library/ee382827.aspx

答案 1 :(得分:2)

当您使用在课程中定义的EF时,您已经定义了关系。 当您在类

中定义Collection中的导航属性时,EF能够理解

public virtual ICollection<Bar> Bars { get; set; }

你想要一对多的关系。

另一方面,如果您将一个集合添加到另一个类

public virtual ICollection<Foo> Foos { get; set; }

EF会明白你想要很多可能关系

如果你在另一个类中添加一个类实例作为属性,它会理解为一对一(或从零到一)关系。

虚拟关键字与您之前提到的关系无关,它涉及懒惰,急切加载