使用单例存储库和工作单元格时附加实体时出错

时间:2018-01-25 13:02:38

标签: c# asp.net entity-framework entity-framework-6 unit-of-work

我们说我有BookAuthor域模型,

public class Book {
  [Key]
  public int Id { get; set; }
  public string BookName { get; set; }
  [ForeignKey="Author"]
  public int AuthorId {get; set;}
  public Author Author { get; set; }
}

public class Author {
  [Key]
  public int Id { get; set; }
  public string AuthorName { get; set; }
  public string Country {get; set;}
}

我已经分离了业务逻辑验证和crud,所以我调用我的验证提供程序来验证addBook服务方法中的新实体。

//BookService.cs
public bool AddBook(AddBook addBook)
{
    // addBook = new { BookName = "Harry Potter", Author = new { Id = 2 } }
    this._validationProvider.Validate(addBook);
    var newBook = _mapper.Map<AddBook, Book>(addBook);
    // i need to get newBook.Author.Country, so attach it,
    _uow.Repository<Author>.Attach(addBook.Author); //<<<------ Exception is here
    //Exception "An object with the same key already exists in the ObjectStateManager. 
    //The ObjectStateManager cannot track multiple objects with the same key."
    _uow.Repository<Author>().Entry(addBook.Author).Reload();
}

//BookValidate.cs
public bool Validate(Addbook addBook)
{
    var author = _uow.Repository<Author>().GetById(addBook.Author.Id); //it's attached
    //checking author etc.
}

问题是,我必须在addBook.Author方法中附上AddBook,因为我不知道并且不介意Validate方法中发生的事情。这可能是由其他人写的,它是商业逻辑验证。

但是在那个业务逻辑验证方法中,他们已经附加了addBook.Author,我收到了以下错误消息,

我该如何处理这个问题?

  

异常&#34;具有相同密钥的对象已存在于   ObjectStateManager。 ObjectStateManager无法跟踪多个   具有相同键的对象。&#34;

2 个答案:

答案 0 :(得分:1)

通常,Validate方法不需要跟踪Author条目。 如果可以将查询标记为无跟踪,请检查您的存储库。

EntityFramework中,您可以将方法AsNoTracking()添加到Linq语句中。

现有问题已解答与此问题相关: https://stackoverflow.com/search?q=ObjectStateManager+cannot+track+multiple+objects+

答案 1 :(得分:1)

我可以看到你只需要作者作为Id的参考。所以你只需要设置Book.AuthorId属性......而不是Book.Author.Id ...

addBook = new {BookName =“Harry Potter”,AuthorId = 2}

这可以解决您的问题并使您的逻辑准确无误。

您也可以更改按条目附加。

商业

 _uow.Repository<Author>.Entry(addBook.Author); 

存储库

Entry<T>(T entity)
{
    this.context.Entry(entity).EntityState = EntityState.Unchanged
}