使用单例存储库和工作单元模式时附加实体时出错
Error in attaching entity when using singleton Repository and Unit of Work Pattern
假设我有 Book
和 Author
领域模型,
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
方法中附加 addBook.Author
,因为我不知道也不介意 Validate
方法中发生了什么。那可能是别人写的,是业务逻辑验证。
但在该业务逻辑验证方法中,他们已经附加了 addBook.Author
,我收到了以下错误消息,
我该如何处理这种问题?
Exception "An object with the same key already exists in the
ObjectStateManager. The ObjectStateManager cannot track multiple
objects with the same key."
一般来说,Validate
方法不需要跟踪Author
条目。
如果可以将查询标记为无跟踪,请检查您的存储库。
在 EntityFramework
中,您可以将方法 AsNoTracking()
添加到 Linq
语句。
已回答与此问题相关的现有问题:
https://whosebug.com/search?q=ObjectStateManager+cannot+track+multiple+objects+
我看你只需要author作为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
}
假设我有 Book
和 Author
领域模型,
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
方法中附加 addBook.Author
,因为我不知道也不介意 Validate
方法中发生了什么。那可能是别人写的,是业务逻辑验证。
但在该业务逻辑验证方法中,他们已经附加了 addBook.Author
,我收到了以下错误消息,
我该如何处理这种问题?
Exception "An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key."
一般来说,Validate
方法不需要跟踪Author
条目。
如果可以将查询标记为无跟踪,请检查您的存储库。
在 EntityFramework
中,您可以将方法 AsNoTracking()
添加到 Linq
语句。
已回答与此问题相关的现有问题: https://whosebug.com/search?q=ObjectStateManager+cannot+track+multiple+objects+
我看你只需要author作为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
}