2

使用实体框架时,我对需要在哪里定义两个实体之间的关系感到困惑。我觉得每当我寻找例子时,我最终都会从两个不同的角度找到同一事物的例子——依赖→主体,以及主体→依赖。

给定以下实体:

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有很多Bars 指向它。Baz有一个可选的外键BarBaz可以存在而不Bar指定。

我将在哪里定义这些关系?在哪里,我的意思是在使用流式 API 时,这些关系将与哪个实体相关联?也许更清楚一点,如果我使用流畅的 API 和EntityTypeConfiguration类进行绑定,这些将在哪个实体中定义?

我感到困惑的一个例子是,我看到类似这样的答案,说应该在类中定义一对一的virtual. Baz因此,在这些实体中,和之间的可选一对一Bar将是,或类似于:

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

2 回答 2

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

至于你的例子中的其他关系Fooand BarFoo有一个集合,BarsFoo只有一个Bar,所以外键继续Bar。EF 默认会这样做。

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

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

于 2013-10-25T03:52:42.770 回答
2

当您按照在类中定义的方式使用 EF 时,您已经定义了关系。EF 能够理解,当您在类中的 Collection 中定义导航属性时

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

你想要一对多的关系。

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

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

EF 会明白你想要很多关系

如果您在另一个类中添加一个类的实例作为属性,也会发生同样的事情,它将理解为一对一(或零对一)关系。

如前所述, virtual关键字与您的关系无关,它与延迟加载有关

于 2013-10-25T04:13:58.690 回答