如何修复此错误:'The instance of entity type cannot be tracked...'



这是完整的错误:

System.InvalidOperationException:"无法跟踪实体类型'Book'的实例,因为已跟踪键值为'{BookId: 382234c3-721d-4f34-80e5-57657bbbbb32}'的另一个实例。附加现有实体时,请确保仅附加一个具有给定键值的实体实例。

当我尝试从业务逻辑层中的服务向数据库添加新实体时,它会引发。我使用了 EF Core,制作了存储库和工作单元,以便在数据访问层中与数据库进行交互。

下面是一些抛出错误的代码,它位于存储库中:

public void Create(T entity)
{
this.LibraryContext.Set<T>().Add(entity);
}

反过来,它从这里调用:

public bool TakeBookById(Guid bookId, Guid studentId, DateTime issueDate) // student takes the book from library
{
var book = mapper.Map<BookDto>(unit.Books.FindByCondition(x => x.BookId == bookId).FirstOrDefault()); // take that book for later using 
if (book != null && book.IsAvailable == true) // if this book is available
{
var student = mapper.Map <StudentDto>(unit.Students.FindByCondition(x => x.StudentId == studentId).FirstOrDefault()); // look for that student
if (student != null && student.LibraryCard.Fields.Where(x => x.Book.IsAvailable == false).Count() <= 10)
{ // if student exists and his/her limit of non-returned books is not exceeded
var libraryCard = mapper.Map<LibraryCardDto>(student.LibraryCard); // take his/her library card
unit.LibraryCardFields.Create( // create library card's field with current data
mapper.Map<LibraryCardField> ( 
new LibraryCardFieldDto()
{
Id = Guid.NewGuid(), // generate new id
Book = book, // student got this book
LibraryCard = libraryCard, // field is in this library card
IssueDate = issueDate, // note current date
ReturnDate = null // student still didn't return it
} )
); 
unit.Save(); // save changes
return true;
}
else { return false; }    
}
else { return false; }    
}

以下是我调用服务方法的代码,为清楚起见,尽可能进行硬编码:

StudentService sts = new StudentService("Server=.\SQLEXPRESS;Database=StudentsLibrary;Trusted_Connection=True;");
sts.TakeBookById(Guid.Parse("382234C3-721D-4F34-80E5-57657BBBBB32"), Guid.Parse("382C74C3-721D-4F34-80E5-57657B6CBC27"), DateTime.Now);

我还应用了我在存储库中使用的方法:

public IEnumerable<T> FindAll()
{
return this.LibraryContext.Set<T>();
}
public IEnumerable<T> FindByCondition(Expression<Func<T, bool>> expression)
{
return this.LibraryContext.Set<T>().Where(expression);
}

我没有在存储库中使用 AsNoTracking((,因为我希望延迟加载工作(我不想为每个模型编写所有 Inlude&ThenInclude 内容(。

我想,如果这本书被跟踪,那么我可以让上下文停止跟踪它。我写了这样的东西:

public void Reset()
{
var entries = libraryContext.ChangeTracker.Entries().ToArray();
foreach (var entry in entries)
{
entry.State = EntityState.Detached;
}
}

并尝试了这个:

public void Reset()
{
libraryContext.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
}

你知道吗?仍然存在该错误。我不知道也许这一切都是因为地图绘制器?

更新:这是因为映射器。但是我该如何解决这种情况呢?如果在创建方法中我创建 DAL 模型的对象,它可以工作。我无法创建 BLL 模型的对象,然后对其进行映射。EF受不了这些东西。

请帮帮我。我是 EF 的新手。

删除自动映射器。键入自己的扩展方法只需几秒钟,并且您可以轻松地完全控制它。

您的主要问题是您创建DTO然后将其转换为实体,并且您没有正确配置。完全跳过该部分,只创建实体。使用这样的DTO是没有意义的。看看下面的代码。

unit.LibraryCardFields.Create( // create library card's field with current data
mapper.Map<LibraryCardField> ( 
new LibraryCardFieldDto()
{
Id = Guid.NewGuid(), // generate new id
Book = book, // student got this book
LibraryCard = libraryCard, // field is in this library card
IssueDate = issueDate, // note current date
ReturnDate = null // student still didn't return it
} )
); 

更改此设置以创建自己的扩展方法并自行转换。

以这个为例。

假设您传入了 DTO 而不是创建它。

var LibraryCardField = LibraryCardFeildDto.ToEntity();//ToEntity is your extension method
unit.LibraryCardFields.Create(LibraryCardField);

为扩展方法创建一个新类。

public static class ExampleMapperClass //or w/e you want to call it{
public static LibaryCardField ToEntity(this LibraryCardFieldDto lbf){
return new LibraryCardField{
Id = lbf.Id,
Book = lbf.book.ToEntity(),//create another extension method for this one
LibraryCard  = LibraryCardDto.ToEntity(),//same here
IssueDate = lbf.issueDate,
ReturnDate = lbf.returnDate
};
}  
}

相关内容

最新更新