不使用跟踪导航属性EF核心

时间:2020-03-07 12:48:44

标签: c# entity-framework entity-framework-core

比方说,我有2张桌子:书籍和作者。它们表示为以下EF模型:

class Book {
   Guid Id { get; set; }
   string BookName { get; set; }
   Author Author { get; set; }
}

class Author {
   Guid Id { get; set; }
   string Name { get; set; }
}

两个实体都有自动生成的Guid ID,即在插入数据库之前,ID是在客户端站点上生成的(这是npgsql的默认行为) 图书表具有作者表的外键。 所以,可以说我已经有几个作者了。我想添加一些作者的新书。这是一个网络应用程序,因此我将存储库注入了控制器。在插入新书之前,我会加载(只读,即,为获得性能收益的AsNoTracking)可用的作者,找到所需的作者并将该作者分配给新创建的书的Author属性。在DbContext.SaveChanges上,我收到一个错误,说给定的ID已经存在。我怀疑EF尝试添加具有给定ID(即使它已经存在于数据库中)的新Author,因为Author实体已加载为NoTracking。

是否可以加载外键,因为没有跟踪来创建新实体?

谢谢

1 个答案:

答案 0 :(得分:1)

Add方法的行为是将通过导航属性发现的任何未跟踪实体递归地标记为Added

因此,您必须在调用Attach之前Add个现有的相关实体,或者使用Entry方法并将State设置为Added-在EF6中效果与Add相同,但是在EF Core中,它只是将实体标记为Added,而没有进行任何导航属性处理。

例如以下将满足您的要求:

var book = new Book { BookName = "SomeBook" };
book.Author = context.Authors.AsNoTracking().First(a => a.Name == "SomeAuthor");
context.Entry(book).State = EntityState.Added;
context.SaveChanges();