2015-10-07 175 views
6

我想用我的数据模型(这是EF 7用来构建我的模式)将我的域模型(它负责我的业务逻辑)分开。实体框架7(Beta 7)和实体跟踪

我遇到了一个问题,关于坚持到我的域模型修改了自己的数据库

因此,例如,因为我有数据模型代码PersonTable和领域模型的人:

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(); 
} 

当我尝试应用这些更改,我得到一个InvalidOperationExceptio n说

“实体类型'Tables.PersonTable'的实例无法跟踪,因为具有相同键的此类型的另一个实例已被跟踪。对于新实体,请考虑使用IIdentityGenerator生成唯一的键值。“

我认为这与实体跟踪有关,但EF 7如何工作?我希望能够应用此模式,以便我可以单独的这两款车型。

回答

3

当你的PersonDbContext实例已经用相同的ID跟踪Person实例时发生错误。

要调试此,检查你所拥有的跟踪已经在PersonDbContext.ChangeTracker.Entries(),我想你会发现你已经有一个PersonTable.Id的条目,它与你试图更新的条目相匹配。

为了确保你没有得到这些冲突,不要重复使用跨线程或多个HTTP请求PersonDbContext(如果这是一个Web应用程序。)

+0

它可能是我的DI造成这种情况吗? Update方法存在于依赖性中,该依赖性被注入到也被注入到控制器的服务中(对于HTTP请求) – Lutando

+1

在进行查询时通过使用PersonDbContext.PersonTable.AsNoTracking()来解决它。 – Lutando

+0

这可能是DI。如果没有在正确的使用期限内注册,通常会发生这种情况。 – natemcmaster

8
// 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);