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

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

Това е нашият сервизен метод, който добавя артикул към собственост

Property е таблица, Item е таблица, PropertyItem е таблицата, включена във връзката много към много.

EF не генерира обект за PropertyItem, така че се опитвам да добавя елементи чрез обекта на свойството. Промяната на свойството за навигация за елементи в свойството не запазва промените.

Опитах Lazy Loading, но няма разлика

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, проследяващ промените, промените в отношенията не се откриват, така че промените не се прилагат към DB.

Така че трябва да внедрите този метод в едно от вашите хранилища.

Има друга опция, която изпълнява директно SQL INSERT команда със съответните ключове, т.е. изпълнява INSERT INTO PropertyItem( <col names>) VALUES (<col values parameters>). За да направите това, трябва да използвате DbContext. Database.ExecuteSqlCommand, който приема заявката и съответните параметри. Ако го направите по този начин, DbContext няма да разбере незабавно за промените в отношенията, но тъй като използвате краткотрайни DbContexts, това не е проблем за вас.

person JotaBe    schedule 10.07.2014