Единый метод Entity Framework для сохранения / обновления - PullRequest
3 голосов
/ 28 сентября 2011

Проблема в том, что я пытаюсь найти единственный способ сохранить объект, будь то новый объект или уже загруженный объект. Большинство примеров кода разделяют методы Add и Save, что противоречит многим другим текущим схемам использования одного метода Save ().

Позвольте мне заявить, что я прочитал другие посты. Я также посмотрел блог команды по шаблону репозитория, в котором есть единственный метод AddObject (), который я не могу найти, предполагая, что это просто Add (объект).

Если мы загружаем объект и сохраняем его, контекст знает об этом. Новый объект, который мы ДОЛЖНЫ добавить. Если мы добавим существующий объект - он отправит его как вставку.

Я хочу одну процедуру сохранения здесь. Пользователь не должен знать, чтобы вызвать Add или Update, достаточно Save (). С учетом вышесказанного, какой лучший маршрут здесь для единственного решения по сохранению, которое охватывает тот же метод (только сохранение, а не загрузка): 1. загрузка объекта, сохранение обратно в БД. 2. Создание нового объекта, сохранение его в БД. Поэтому я ищу реализацию, которая во всех случаях может быть

ICustomerRepository.Save(Customer customer)

Какое решение вы бы использовали, который работает?

Мне кажется, что следующий код в методе Save (entity) работает для меня


//If the primary key is empty, its a new record
if (order.OrderId == 0)
{
   _context.Orders.Add(order);
}

if (_context.Entry(order).State == System.Data.EntityState.Detached)
{
   //Need to set modified so any detached entities are updated otherwise they won't be sent across to the db. Since it would've been outside the context, change tracking wouldn't have occurred anyways so we have no idea about its state - save it!
   _context.Orders.Attach(order);
   _context.Entry(order).State = System.Data.EntityState.Modified;
}


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

Ответы [ 3 ]

2 голосов
/ 28 сентября 2011

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

EF не поддерживает единый метод обработки и не может быть просто добавлен. Чтобы заставить его работать правильно, вам понадобится что-то на уровне SQL для условной вставки / обновления (или слияния в SQL Server 2008). У EF ничего подобного нет, и он разделяет обе операции вплоть до выполнения команды.

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

1 голос
/ 19 июля 2013
public abstract class EntityObject
{
    /*Allows for this:
        T UpdateOrInsert<T>(T item) where T : EntityObject
        {
            T foundItem = depDA.Set<T>().Find(item.EntityKey);
            return foundItem;
        }
    etc


     inherit entity partials from this

     partial class MyObject : EntityObject
     {
         override int EntityKey { get { return MyObjectID; } } 
     }

    */

    public abstract int EntityKey { get; }

}

вставьте этот метод в класс Helper

public static T SaveEntity<T>(T item, DbContext context) where T : EntityObject
{
    T foundItem = context.Set<T>().Find(item.EntityKey);
    if (foundItem == null)
    {
        //INSERT
        foundItem = context.Set<T>().Add(item as T);
    }
    else
    {
        //UPDATE
        foundItem = item;
    }
    context.SaveChanges();
    return foundItem;
}

Вуаля!

0 голосов
/ 28 сентября 2011

Если вы используете объекты самообследования, то объект будет отслеживать состояние и вставлять или обновлять по мере необходимости, без необходимости использования отдельных методов

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...