实体框架“实体对象不能被IEntityChangeTracker的多个实例引用”

时间:2016-06-23 11:34:16

标签: c# entity-framework entity-framework-6

我收到错误

  

实体对象不能被多个实例引用   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();
        }
    }
}

4 个答案:

答案 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。