我收到错误
实体对象不能被多个实例引用 IEntityChangeTracker
尝试创建新实体并将其保存到数据库时。
我理解错误以及它是如何正常发生的,但在这种情况下,我所做的只是在保存之前创建一个新实体并向其添加一些int
,而不是从其他上下文添加任何其他实体。
我已经包含了导致错误的函数。正如您所看到的那样,它正在传递EndProduct
,这是一个实体,它被_billableRepository
中不同的上下文跟踪,但由于我不想尝试将该实体分配给int
。新创建的计费我不明白它是怎么回事。
我可以看到发生错误的唯一方法是,分配给新Billable
的{{1}}个值取自正在跟踪的现有EndProduct
通过不同的上下文,但IEntityChangeTracker
肯定不会跟踪实体的各个基元?
public void AddBillable(EndProduct endProduct, int? purchaseId, string centreCode, int userId)
{
if (endProduct.Product != null)
{
var existingBillableForUserForProductId = _billableRepository.GetQuery(b => b.UserId == userId && b.ProductId == endProduct.ProductId);
if (endProduct.BillablePartId != null && !existingBillableForUserForProductId.Any())
{
var billable = new Billable {
ProductId = endProduct.ProductId.Value, //int
UserId = userId, //int
PartId = endProduct.BillablePartId.Value, //int
DateAdded = DateTime.UtcNow, //datetime
PurchaseId = purchaseId, //int
CentreCode = centreCode //string
};
_billableRepository.Add(billable); //error here
_billableRepository.UnitOfWork.SaveChanges();
}
}
}
答案 0 :(得分:11)
最可能的原因是您正在使用的任何依赖注入工具。
每单位工作应该只有一个DbContext
。如果您每次都要新建一个新的,请确保丢弃旧的。
否则,您将有多个相同上下文的实例并排运行。
这是变更跟踪器混淆的地方,无法跟踪实体的变化。
答案 1 :(得分:2)
此示例代码将解决问题;
public class DataModel
{
private static DBContext context;
public static DBContext Context
{
get
{
if (context == null)
{
context = new SozlukContext();
return context;
}
return context;
}
}
}
public class EntryRepository : IEntryRepository
{
DBContext _context = DataModel.Context;
public IEnumerable<Data.Model.Entry> GetAll()
{
return _context.Entry.Select(x => x);
}
}
答案 2 :(得分:2)
在您的模型上(GetById method)
尝试输入以下内容:
var billable = _db.Billable.
的 AsNoTracking()强> .SingleOrDefault(i => i.BillableId == id);
使用 AsNoTracking(),以便它返回一个新查询,其中的实体不会缓存在System.Data.Entity.DbContext
答案 3 :(得分:1)
您可以通过在存储库中附加实体来修复。像这样:
_context.Set<T>.Attach(entity)
在上下文中设置其DbSet。