Entity Framework “An entity object cannot be refer

2020-07-10 06:33发布

I am getting the error

An entity object cannot be referenced by multiple instances of IEntityChangeTracker

when trying to create a new entity and save it to the DB.

I understand the error and how it normally occurs, but in this instance all I am doing is creating a new entity and adding a few ints to it before saving, not adding any other entities from other contexts.

I have included the function that is causing the error. As you can see it is being passed an EndProduct which is an entity which is being tracked by a different context to the one in the _billableRepository, but since I am not trying to in anyway assign that entity to the newly created billable I don't see how it can be a problem.

The only way I can see the error happening is because a couple of the int values that are being assigned to the new Billable are taken from the existing EndProduct that is being tracked by a different context, but surely the IEntityChangeTracker doesn't track the individual primitives of an entity?

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条回答
成全新的幸福
2楼-- · 2020-07-10 06:51

On your model (GetById method) try to put something like this:

var billable = _db.Billable.AsNoTracking().SingleOrDefault(i => i.BillableId == id);

Use AsNoTracking() so that it returns a new query where the entities will not be cached in the System.Data.Entity.DbContext

查看更多
别忘想泡老子
3楼-- · 2020-07-10 07:01

This sample code will solve the problem;

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);
        }
    }
查看更多
何必那么认真
4楼-- · 2020-07-10 07:04

You can fix by attaching your entity in the repository. Like this:

_context.Set<T>.Attach(entity)

Where Set its your DbSet in the context.

查看更多
家丑人穷心不美
5楼-- · 2020-07-10 07:05

The most likely cause of this is to do with any dependency injection tool you're using.

There should only be one DbContext in play per unit of work. If you are newing up a new one each time, make sure the old one is disposed of.

Otherwise, you will have multiple instances of the same context running alongside each other.

This is where the change tracker gets confused and is unable to track changes to your entities.

查看更多
登录 后发表回答