c# - Entity Framework Code First 关联/FK 问题和假设/默认值

标签 c# entity-framework ef-code-first

我对 Entity Framework 处理实体之间关系的方式感到非常困惑。我有几个问题。

在一个简单的测试应用程序中,我有一张人物表、一张笔记表和一张图片 Assets 表。

  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 是非可以为 null 且 FK 尚不存在。

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

最佳答案

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

向下滚动以获取有关您的澄清的答案。

这里有两种方法可以实现,一种方法是删除 cross reference通过申请导航 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。如果你的 key 没有命名为ID,你需要添加一个KeyAttribute ,在这种情况下,我们还添加了 ForeignKeyAttribute .

请注意您应该使用virtual因此只有在您请求时才加载,如果您只想要人名,您很可能不希望数据库查询图片信息。

Association properties that are marked as virtual will by default be lazy-loaded. What this means is that if you retrieve a Product entity, its Category information will not be retrieved from the database until you access its Category property (or unless you explicitly indicate that the Category data should be retrieved when you write your LINQ query to retrieve the Product object).

Scott Gu - Using EF Code First with an existing database


关于您的澄清的新答案:

通过使用 ICollection<T> 返回 1:N 结构进一步构建外键;一旦你找到你喜欢的人 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<Picture> Pictures { get; set; }
        public ICollection<Note> 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; }
    }

关于c# - Entity Framework Code First 关联/FK 问题和假设/默认值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7638992/

相关文章:

c# - 在 Entity Framework 数据库优先方法中如何从存储过程返回多个结果集?

c# - 如何在 Entity Framework Code First 中删除一个表?

c# - 从字符串输入中获取命令

c# - 为什么在计时器中绘画会导致应用程序变得无响应

c# - 在多层应用程序的 DbContext 上使用 Ninject

entity-framework - 使用 POCO 时,我应该保持外键与引用同步吗

c# - EF Code First 不为 ICollection<string> 生成表

c# - 何时使用 SemanticModel.GetSymbolInfo 以及何时使用 SemanticModel.GetDeclaredSymbol

c# - 在 C# - C++/CLI - C++ Windows 窗体应用程序退出之前跟踪 - 并正确结束 - native 和托管线程

entity-framework - 异步 ObjectContext.SaveChanges()?