entity framework代码第一个关联/ FK问题和假设/默认值

我对entity framework能够了解实体之间关系的方式感到非常困惑。 我对此有几个问题。

在一个简单的测试应用程序中,我有一个人员表,一个笔记表和一个图片资产表。

  1. 有很多图片,每个都是由一个人拥有(一个人可以拥有多个)。
  2. 有许多笔记,每个笔记都由一个人拥有(一个人可以拥有多个)。
  3. 最后一个人有一个标志,这是一张图片。

public class Person { public int ID { get; set; } public string name { get; set; } public Picture logo { get; set; } } public class Note { public int ID { get; set; } public string Text { get; set; } public Person Owner { get; set; } } public class Picture { public int ID { get; set; } public string Path { get; set; } public Person Owner { get; set; } } 

当我尝试运行时,我收到错误“无法确定类型之间的关联的主要结束….”。

(如果我删除Person.logo字段,编译/运行,然后手动将其添加到SQL,以及FK关系,它按预期工作100%…我似乎无法弄清楚如何设置此来自EF本身)。

你能帮忙解决这个错误吗? 我在这里已经阅读了不少答案,但是,我似乎无法适应它来修复我的错误。

但是,现在我有一对多和多对一(我不认为这被归类为多对多?),我只是不明白如何创建人物对象,其中FK不可为空而且FK尚不存在。

我找到的解决方案,我真的不喜欢的是让person.picture列可以为空,然后创建一个人,然后创建一个图片,然后将图片分配给person对象……但是,理想情况下我不喜欢我希望它可以为空。 应该总是有一张照片。

假设您的1:1关系的旧答案:

向下滚动以获得澄清答案。

以下是实现此目的的两种方法,一种方法是通过应用1:N来删除交叉引用导航。

  public class Person { public int ID { get; set; } public string Name { get; set; } public virtual Picture Logo { get; set; } } public class Note { public int ID { get; set; } public string Text { get; set; } } public class Picture { public int ID { get; set; } public string Path { get; set; } } 

这是一个非常便宜的解决方案,你可能不需要比人更多的笔记或图片……

因此,使用Data Annotations来指示外键是什么,这将保持导航和1:1 。

  public class Person { public int ID { get; set; } public string Name { get; set; } public virtual Picture Logo { get; set; } } public class Note { [Key, ForeignKey("Person")] public int OwnerID { get; set; } public string Text { get; set; } public virtual Person Owner { get; set; } } public class Picture { [Key, ForeignKey("Person")] public virtual int OwnerId { get; set; } public string Path { get; set; } public virtual Person Owner { get; set; } } 

如您所见,由于1:1的关系,图片和笔记将使用相同的ID。 如果您的密钥不是命名ID,则需要添加KeyAttribute ,在这种情况下,我们还要添加ForeignKeyAttribute 。

请注意,您应该使用virtual以便仅在您请求时加载内容,如果您只需要Person的名称,则很可能不希望数据库查询图片信息。

默认情况下,标记为virtual关联属性将是延迟加载的。 这意味着,如果您检索Product实体,则在您访问其Category属性之前,将不会从数据库中检索其类别信息(或者除非您在编写LINQ查询以检索其时明确指出应检索类别数据。产品对象)。

– Scott Gu – 将EF Code First与现有数据库结合使用


关于澄清的新答案:

通过返回具有ICollection的1:N结构ICollection键上进一步建立; 一旦你获得像var boss = Person.Find(BossID)你就可以访问boss.Pictures ,它将拥有各种图片。 您也可以将boss.Logo指定为其中一张图片。

  public class Person { public int ID { get; set; } public string Name { get; set; } public virtual Picture Logo { get; set; } public ICollection Pictures { get; set; } public ICollection Notes { get; set; } } public class Note { public int ID { get; set; } [ForeignKey("Person")] public int OwnerID { get; set; } public string Text { get; set; } public virtual Person Owner { get; set; } } public class Picture { public int ID { get; set; } [ForeignKey("Person")] public virtual int OwnerId { get; set; } public string Path { get; set; } public virtual Person Owner { get; set; } } 

您可能有兴趣使用DataAnnotations来暗示您的数据成员,以及查看当前的Code First约定 。

 public class Person { public int ID { get; set; } public string Name { get; set; } public virtual Picture Logo { get; set; } public ICollection Pictures { get; set; } public ICollection Notes { get; set; } } public class Note { public int ID { get; set; } public int OwnerID { get; set; } public string Text { get; set; } [ForeignKey("OwnerId")] public virtual Person Owner { get; set; } } public class Picture { public int ID { get; set; } public virtual int OwnerId { get; set; } public string Path { get; set; } [ForeignKey("OwnerId")] public virtual Person Owner { get; set; } } 

上面的代码是正确的,在多次尝试错误的代码后,我得到了正确的代码。

希望它对你有用。