c# - 在 EF Code First 中, Foo 是否可以拥有 Bars 集合以及 "FavouriteBar"?

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

为了说明我的问题,假设我有一个数据模型,其中有一组书籍,每本书都有一个或多个草稿,还有一个“当前”草稿。我希望我的模型看起来像这样:

class Book
{
    public int Id { get; set; }

    public string Title { get; set; }

    public virtual ICollection<Draft> Drafts { get; set; }

    public virtual Draft CurrentDraft { get; set; }
}

class Draft
{
    public int Id { get; set; }

    public virtual int BookId { get; set; }
    public virtual Book Book { get; set; }

    public string Description { get; set; }
}

我有一个如下所示的 DbContext:

class TestDbContext : DbContext
{
    public DbSet<Book> Books { get; set; }
    public DbSet<Draft> Drafts { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
        modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();

        base.OnModelCreating(modelBuilder);
    }
}

...以及一个像这样的简单程序:

static void Main(string[] args)
{
    Database.SetInitializer<TestDbContext>(new DropCreateDatabaseAlways<TestDbContext>());

    using (var db = new TestDbContext())
    {
        var book = new Book() { Title = "War and Peace", Drafts = new List<Draft>() };


        var draft1 = new Draft() { Book = book, Description = "First Draft" };

        book.Drafts.Add(draft1);


        var draft2 = new Draft() { Book = book, Description = "Second Draft" };

        book.Drafts.Add(draft2);


        book.CurrentDraft = draft2;


        db.Books.Add(book);

        db.SaveChanges();


        foreach (var b in db.Books)
        {
            Console.WriteLine("Book {0}: {1}", b.Id, b.Title);

            foreach (var d in book.Drafts)
                Console.WriteLine("\tDraft ID {0}: {1} from Book ID {2}", d.Id, d.Description, d.BookId);

            Console.WriteLine("Current draft has ID {0}", b.CurrentDraft.Id);
        }

        Console.ReadKey();
    }
}

当EF创建DB时,它看起来像这样:

database schema

[我并不热衷于额外的 Book_Id 列,但如果它有效的话我可以接受。]

遗憾的是,当我运行测试程序时,它在 SaveChanges 调用时失败,但有一个异常(exception):

An error occurred while saving entities that do not expose foreign key properties for their relationships. The EntityEntries property will return null because a single entity cannot be identified as the source of the exception. Handling of exceptions while saving can be made easier by exposing foreign key properties in your entity types. See the InnerException for details.

我尝试在 OnModelCreating 中使用 Fluent API,但是当我尝试以这种方式配置它时,它会因为 Books 和 Drafts 之间存在两种 FK 关系而感到困惑。我对 Fluent 的东西(或者一般的 EF)不太熟悉,不知道如何正确地做到这一点。

这在 EF 代码中是否可行?

最佳答案

您的内部异常是 EF 无法确定将内容保存到数据库以正确创建内容的顺序。如果您在多个位置调用保存更改以强制测试应用程序的工作顺序:

            var book = new Book() { Title = "War and Peace", Drafts = new List<Draft>() };
            db.Books.Add(book);
            db.SaveChanges();
            var draft1 = new Draft() { Book = book, Description = "First Draft" };
            book.Drafts.Add(draft1);
            var draft2 = new Draft() { Book = book, Description = "Second Draft" };
            book.Drafts.Add(draft2);
            book.CurrentDraft = draft2;
            db.SaveChanges();

关于第二个 book_id - 你可以使用这个流利的:

        modelBuilder.Entity<Book>()
            .HasMany(b => b.Drafts)
            .WithRequired(d => d.Book)
            .HasForeignKey(d => d.BookId);

        modelBuilder.Entity<Book>()
            .HasOptional(b => b.CurrentDraft)
            .WithOptionalDependent()
            .Map(m => m.MapKey("CurrentDraftId"));

生成此数据库:

enter image description here

关于c# - 在 EF Code First 中, Foo 是否可以拥有 Bars 集合以及 "FavouriteBar"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12805572/

相关文章:

c# - 应该在 Repository 或 Service 层编写复杂的查询?

c# - 首先修改由 EF5 代码创建的多对多表

c# - 在 Configuration.cs 中播种数据,使用 AddOrUpdate 创建重复数据

c# - 如何使用 textile.net

c# - 检查 List<List<int>> 是否包含 List<int>

c# - WPF MVVM 中的 NHibernate session

c# - DbArithmeticExpression 参数必须具有数字通用类型

entity-framework - EF : Can I mix TPH and TPT when abstract base and a few concrete types are in TPH-table and other types have their own table?

entity-framework - 使用linq获取模型类Entity Framework Code First的NotMapped属性中的值

c# - 如何使用 ASP.NET MVC 中的 Entity Framework 将记录插入到具有外键的表中