我试图将我的域模型(负责我的业务逻辑)与我的数据模型分开,这是EF 7用来构建我的模式的。
我遇到了一个问题,关于对我的域模型对我的数据库所做的持久更改
例如,我有数据模型PersonTable和域模型Person:
public class PersonTable
{
public virtual Guid Id { get; set; }
public virtual String Name { get; set; }
public virtual String Surname { get; set; }
}
public class Person
{
public virtual Guid Id { get; set; }
public virtual String Name { get; set; }
public virtual String Surname { get; set; }
//Other Domain Methods and Constructors...
}
我想通过以下方式将域更改持久化到数据库:
public void Update(Person p)
{
var person = new PersonTable
{
Id = p.Id,
Name = p.Name,
Surname = p.Surname
}
PersonDbContext.Update(person);
PersonDbContext.SaveChanges();
}
当我尝试应用这些更改时,我得到一个InvalidOperationException说
"实体类型'Tables '的实例。无法跟踪PersonTable,因为已经跟踪了具有相同键值的该类型的另一个实例。对于新实体,可以考虑使用IIdentityGenerator来生成唯一的键值。"
我认为这与实体跟踪有关,但这在EF 7中是如何工作的?我希望能够应用这个模式,这样我就可以把这两个模型分开。
// Before updating we have fetch original data row from database.
// So we need to use AsNoTracking().
var originalPerson = PersonDbContext.Person.AsNoTracking().FirstOrDefault(p => p.Id == id);
和保存时,我们需要使用以下代码:
PersonDbContext.Entry(originalPerson).Context.Update(newPersonDetail);
当您的PersonDbContext
实例已经跟踪具有相同Id的Person
实例时,会发生错误。
要调试这个,检查您已经在PersonDbContext.ChangeTracker.Entries()
中跟踪的内容。我希望您会发现您已经有一个PersonTable.Id
条目,该条目与您试图更新的条目相匹配。
为了确保你不会得到这些冲突,不要跨线程或多个HTTP请求(如果这是一个web应用程序)重用PersonDbContext
我也面临同样的错误。我在另一个帖子里找到了答案https://stackoverflow.com/a/31840042/1716912。