Как сохранить изменения свойств навигации с помощью Entity Framework

Я пытаюсь добавить составной ключ в таблицу «многие ко многим», используя структуру сущностей, но он не добавляет ключ.

Это наш сервисный метод, который добавляет элемент к свойству.

Property — это таблица, Item — это таблица, PropertyItem — это таблица, участвующая в отношении «многие ко многим».

EF не создает сущность для PropertyItem, поэтому я пытаюсь добавить элементы через сущность свойства. Изменение свойства навигации для элементов в свойстве не сохраняет изменения.

Я пробовал ленивую загрузку, но это не имеет значения

public void addPropertyItem(int propertyId, int itemId)
    {
        ErrorHandler errorHandler = new ErrorHandler();
        try
        {
            Item item = itemRepo.getSingle(i => i.itemId.Equals(itemId));
            if (item == null)
            {
                errorHandler.addException("Item does not exist.");
            }
            Property property = propertyRepo.getSingle(p => p.propertyId.Equals(propertyId), p => p.Items);
            if (property == null)
            {
                errorHandler.addException("Property does not exist.");
            }

            if (!errorHandler.hasErrors())
            {
                foreach (Item i in property.Items)
                {
                    if (i.itemId == item.itemId)
                    {
                        return;
                    }
                }

                property.Items.Add(item);

                propertyRepo.update(property);
            }

Данные извлекаются с помощью следующего кода:

public virtual T getSingle(Func<T, bool> where,
         params Expression<Func<T, object>>[] navigationProperties)
    {
        T item = null;
        using (var context = new PropertyManagementDBEntities())
        {
            IQueryable<T> dbQuery = context.Set<T>();

            //Apply eager loading
            foreach (Expression<Func<T, object>> navigationProperty in navigationProperties)
                dbQuery = dbQuery.Include<T, object>(navigationProperty);

            item = dbQuery
                .FirstOrDefault(where); //Apply where clause
        }
        return item;
    }

Это обновление на стороне DAL.

public virtual void update(params T[] items)
    {
        using (var context = new PropertyManagementDBEntities())
        {
            foreach (T item in items)
            {
                context.Entry(item).State = System.Data.EntityState.Modified;
            }
            context.SaveChanges();
        }
    }

Любая помощь приветствуется, спасибо,


person user3822333    schedule 09.07.2014    source источник


Ответы (1)


Чтобы делать то, что вы хотите, вам нужно иметь DbContext для отслеживания изменений, то есть вам нужно реализовать такой метод:

using (var context = new PropertyManagementDBEntities())
{
    // Implement here code that
    // 1. Get the Property (or properties)
    // 2. Get the Item (or items)
    // 3. Adds the Item (or items) to the Property (or proerties)
    context.SaveChanges();
}

Таким образом, DbContext отслеживает изменения (т. е. знает о том, что происходит), поэтому он знает о новом отношении (он выполняет «исправление отношения») и при вызове SaveChanges сохраняет новые отношения.

Если DbContext не отслеживает изменения, изменения отношения не обнаруживаются, поэтому изменения не применяются к БД.

Поэтому вам нужно реализовать этот метод в одном из ваших репозиториев.

Существует другой вариант, который выполняет непосредственно команду SQL INSERT с соответствующими ключами, т. е. выполняет команду INSERT INTO PropertyItem( <col names>) VALUES (<col values parameters>). Для этого необходимо использовать DbContext. Database.ExecuteSqlCommand, который принимает запрос и соответствующие параметры. Если вы сделаете это таким образом, DbContext не будет сразу знать об изменениях отношений, но, поскольку вы используете недолговечные DbContexts, это не проблема для вас.

person JotaBe    schedule 10.07.2014