entity framework代码第一个关联/ FK问题和假设/默认值
我对entity framework能够了解实体之间关系的方式感到非常困惑。 我对此有几个问题。
在一个简单的测试应用程序中,我有一个人员表,一个笔记表和一个图片资产表。
- 有很多图片,每个都是由一个人拥有(一个人可以拥有多个)。
- 有许多笔记,每个笔记都由一个人拥有(一个人可以拥有多个)。
- 最后一个人有一个标志,这是一张图片。
。
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
您可能有兴趣使用DataAnnotations来暗示您的数据成员,以及查看当前的Code First约定 。
public class Person { public int ID { get; set; } public string Name { get; set; } public virtual Picture Logo { get; set; } public ICollection
上面的代码是正确的,在多次尝试错误的代码后,我得到了正确的代码。
希望它对你有用。