简体   繁体   English

EF5逆属性问题

[英]EF5 InverseProperty Issue

I'm trying to convert the following model (see image below) to Code First. 我正在尝试将以下模型(参见下图)转换为Code First。 I've tried various combinations involving ForeignKey and InverseProperty attributes with no luck. 我尝试了各种涉及ForeignKey和InverseProperty属性的组合,但是没有运气。 I've found this answer but it seems that combinations of ForeignKey and InverseProperty cause a different behaviour. 我找到了这个答案,但似乎ForeignKey和InverseProperty的组合会导致不同的行为。

The attached source code gives the following error: 随附的源代码给出以下错误:

Unable to determine the principal end of an association between the types 'InversePropertyTest.Author' and 'InversePropertyTest.Book'. 无法确定类型'InversePropertyTest.Author'和'InversePropertyTest.Book'之间的关联的主体端。 The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations. 必须使用关系流利的API或数据注释显式配置此关联的主要端。

This is my model with EDMX 这是我的EDMX模型

型号范例

Sample code: 样例代码:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace InversePropertyTest
{
    public class Author
    {
        public int AuthorId { get; set; }
        public Nullable<int> CurrentlyWorkingBookId { get; set; }

        [InverseProperty("Author")] public ICollection<Book> Books { get; set; }
        [ForeignKey("CurrentlyWorkingBookId"), InverseProperty("EditoredBy")] public Book CurrentlyWorkingBook { get; set; }
    }

    public class Book
    {
        public int BookId { get; set; }
        public int AuthorId { get; set; }

        [ForeignKey("AuthorId"), InverseProperty("Books")] public Author Author { get; set; }
        [InverseProperty("CurrentlyWorkingBook")] public Author EditoredBy { get; set; }
    }

    public class SimpleContext : DbContext
    {
        public DbSet<Author> Authors { get; set; }
        public DbSet<Book> Books { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            using (var context = new SimpleContext())
            {
                IList<Author> authors = (from a in context.Authors select a).ToList();
                IList<Book> books = (from b in context.Books select b).ToList();
            }
        }
    }
}

Any help is greatly appreciated 任何帮助是极大的赞赏

When you use [InverseProperty] at both ends of a 1:1 association it is not clear who the principal should be. 当您在1:1关联的两端使用[InverseProperty]时,不清楚主体应该是谁。 The principle is the entity the other end (the dependent) refers to by a foreign key. 原理是另一端(从属)通过外键引用的实体。 Even though you tell EF that EditoredBy and CurrentlyWorkingBookId both are part of one association it still would be possible to have a foreign key field for EditoredBy in Book (that wouldn't show in the class model). 即使你告诉EF这EditoredByCurrentlyWorkingBookId都是一个协会的一部分,它仍然是有可能有一个外键字段EditoredByBook (将不可能在班级模型显示)。

Admittedly, one could contend that you've told EF enough to create the database model properly. 诚然,您可以说您已经告诉EF足够正确地创建数据库模型。 EF could have logic that says: if I've been told about one foreign key in a 1:1 association, then I know who the principle should be. EF可能有这样的逻辑:如果有人告诉我1:1关联中有一个外键,那么我知道应该是谁。 However, unfortunately it doesn't. 但是,不幸的是事实并非如此。

So I would use the fluent API to model this: 因此,我将使用流畅的API对此进行建模:

public class Author
{
    public int AuthorId { get; set; }
    public ICollection<Book> Books { get; set; }
    public Book CurrentlyWorkingBook { get; set; }
}

public class Book
{
    public int BookId { get; set; }
    public int AuthorId { get; set; }
    public Author Author { get; set; }
    public Author EditoredBy { get; set; }
}

In OnModelCreating : OnModelCreating

modelBuilder.Entity<Author>()
            .HasMany(a => a.Books)
            .WithRequired(b => b.Author)
            .HasForeignKey(b => b.AuthorId);
modelBuilder.Entity<Author>()
            .HasOptional(a => a.CurrentlyWorkingBook)
            .WithOptionalDependent(b => b.EditoredBy)
            .Map(m => m.MapKey("CurrentlyWorkingBookId"));

Personally, I like the fluent API because the lambda expressions allow compile-time checks and it is much more conspicuous which ends comprise one association. 就我个人而言,我喜欢流利的API,因为lambda表达式允许进行编译时检查,而且末端组成一个关联的情况更加明显。

As you see, CurrentlyWorkingBookId can not be part of the class model in this scenario. 如您所见,在这种情况下, CurrentlyWorkingBookId不能成为类模型的一部分。 That is because an OptionalNavigationPropertyConfiguration (the return type of WithOptionalDependent ) doesn't have HasForeignKey method. 这是因为OptionalNavigationPropertyConfigurationWithOptionalDependent的返回类型)没有HasForeignKey方法。 I'm not sure why not. 我不确定为什么不这样做。 I think it should be possible to set a primitive FK value ( CurrentlyWorkingBookId ) as well as a reference property ( CurrentlyWorkingBook ). 我认为应该可以设置原始FK值( CurrentlyWorkingBookId )以及引用属性( CurrentlyWorkingBook )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM