2

我正在尝试将以下模型(见下图)转换为 Code First。我尝试了各种涉及 ForeignKey 和 InverseProperty 属性的组合,但没有成功。我找到了这个答案,但似乎 ForeignKey 和 InverseProperty 的组合会导致不同的行为。

随附的源代码给出以下错误:

无法确定类型“InversePropertyTest.Author”和“InversePropertyTest.Book”之间关联的主体端。此关联的主体端必须使用关系流式 API 或数据注释显式配置。

这是我的 EDMX 模型

型号示例

示例代码:

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();
            }
        }
    }
}

任何帮助是极大的赞赏

4

1 回答 1

1

当您[InverseProperty]在 1:1 关联的两端使用时,不清楚谁应该是委托人。原则是另一端(从属)通过外键引用的实体。即使您告诉 EFEditoredBy并且CurrentlyWorkingBookId两者都是一个关联的一部分,仍然可以为EditoredByin拥有一个外键字段Book(不会在类模型中显示)。

诚然,有人可能会争辩说您已经告诉 EF 足以正确创建数据库模型。EF 可能有这样的逻辑:如果我被告知 1:1 关联中有一个外键,那么我知道该原则应该是谁。然而,不幸的是它没有。

所以我会使用 fluent 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; }
}

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"));

就我个人而言,我喜欢 fluent API,因为 lambda 表达式允许编译时检查,而且哪个结尾包含一个关联更加显眼。

如您所见,CurrentlyWorkingBookId在这种情况下不能成为类模型的一部分。那是因为OptionalNavigationPropertyConfiguration(的返回类型WithOptionalDependent)没有HasForeignKey方法。我不知道为什么不。我认为应该可以设置原始 FK 值 ( CurrentlyWorkingBookId) 以及引用属性 ( CurrentlyWorkingBook)。

于 2013-10-31T16:16:18.910 回答