Entity Framework " объект сущности не может ссылаться на несколько экземпляров IEntityChangeTracker"

Я получаю ошибку

объекта не может ссылаться несколько экземпляров IEntityChangeTracker

при попытке создать новый объект и сохранить его в БД.

Я понимаю ошибку и как это обычно происходит, но в этом случае все, что я делаю, это создание нового объекта и добавление нескольких ints к нему перед сохранением, не добавляя никаких других объектов из других контекстов.

я включил функция, вызывающая ошибку. Как вы можете видеть, он передается EndProduct который является сущностью, которая отслеживается другим контекстом в _billableRepository, но поскольку я не пытаюсь в любом случае назначить эту сущность вновь созданной оплачиваемой, я не вижу, как это может быть проблемой.

единственный способ, которым я могу видеть ошибку, это потому, что пара int значения, которые присваиваются новому Billable взяты из существующего 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 ответов


наиболее вероятной причиной этого является любой инструмент инъекции зависимостей, который вы используете.

должен быть только один DbContext в игре на единицу работы. Если вы каждый раз создаете новый, убедитесь, что старый удален.

в противном случае у вас будет несколько экземпляров одного и того же контекста, работающих вместе друг с другом.

здесь трекер изменений запутывается и не может отслеживать изменения в ваших сущностях.


этот пример кода решит проблему;

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);
        }
    }

модель (GetById method) попробуйте поставить что-то вроде этого:

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

использовать AsNoTracking() так, что он возвращает новый запрос, Где лиц не будут кэшироваться в System.Data.Entity.DbContext


вы можете исправить, прикрепив свой объект в репозитории. Вот так:

_context.Set<T>.Attach(entity)

где установить свой DbSet в контексте.