简体   繁体   English

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

[英]Using no tracking navigation property EF core

Let's say I have 2 tables: Books and Authors.假设我有 2 个表:Books 和 Authors。 They are represented as following EF models:它们表示为以下 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; }
}

Both entities have autogenerated Guid Id, ie before being inserted into database, Ids are generated on client site(that's default behaviour of npgsql) Book table has a foreign key to Author table.两个实体都有自动生成的 Guid Id,即在插入数据库之前,在客户端站点上生成 Id(这是 npgsql 的默认行为) Book 表有一个 Author 表的外键。 So, lets say I have a several authors already.所以,假设我已经有几个作者了。 I would like to add new book by some author.我想添加一些作者的新书。 It's a web app, so I have repositories injected into controller.这是一个网络应用程序,所以我将存储库注入控制器。 Before inserting new book I load (readonly, ie AsNoTracking for performance benefits) available authors, find required author and assign that author to newly created book's Author property.在插入新书之前,我加载(只读,即 AsNoTracking 以提高性能)可用作者,找到所需的作者并将该作者分配给新创建的书的 Author 属性。 On DbContext.SaveChanges I got an error, saying the given Id already exist.在 DbContext.SaveChanges 上我收到一个错误,说给定的 Id 已经存在。 I suspect EF is trying to add new Author with a given ID(even though it already exist in a database) because Author entity was loaded as NoTracking.我怀疑 EF 正在尝试添加具有给定 ID 的新作者(即使它已存在于数据库中),因为作者实体已作为 NoTracking 加载。

Is there a way to load foreign key as no tracking to create new entities?有没有办法将外键加载为无跟踪以创建新实体?

Thanks谢谢

The behavior of the Add method is to mark recursively as Added any non tracked entity discovered via navigation properties. Add方法的行为是以递归方式将通过导航属性发现的任何未跟踪实体标记为已Added

So you either has to Attach the existing related entities before calling Add , or use Entry method and set the State to Added - in EF6 this has the same effect as Add , but in EF Core it just marks the entity as Added without doing any navigation property processing.所以,你要么必须Attach调用之前已有相关实体Add ,或使用Entry法,并设置StateAdded -在EF6这有相同的效果Add ,但在EF核心,它只是标志着实体Added而不做任何导航财产处理。

eg the following will do what you are asking for:例如,以下将执行您的要求:

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

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

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