实体框架7 (Beta 7)和实体跟踪



我试图将我的域模型(负责我的业务逻辑)与我的数据模型分开,这是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。

最新更新