#c# #asp.net-mvc-3 #entity-framework
#c# #asp.net-mvc-3 #entity-framework
Вопрос:
У меня ситуация, когда я извлекаю данные из таблицы по дате. Если на заданную дату данные не предоставлены, я создаю запись, используя значения по умолчанию, и показываю все это пользователю. Когда пользователь закончит манипулировать данными, мне нужно зафиксировать изменения.
Итак, мой вопрос заключается в том, как мне обработать в Entity Framework отправку таблицы, в которой могут быть как обновления, так и добавления, которые необходимо выполнить. Это на C # с использованием MVC3 и Entity Framework.
Итак, вот как могут выглядеть данные для начала,
Таблица A
NAME AGE PHONE_NUM
Jim 25 555-555-5555
Jill 48 555-551-5555
После того, как пользователи закончили с данными, это может выглядеть так,
Таблица A
NAME AGE PHONE_NUM
Jim 25 555-555-5555
Jill 28 555-551-5555
Rob 42 555-534-6677
Как мне зафиксировать эти изменения? Моя проблема в том, что требуются как обновления, так и вставки?
Я нашел некоторый подобный код, но я не знаю, сработает ли он в этом случае.
Для добавления строк данных
entities.TABlEA.AddObject(TableOBJECT);
entities.SaveChanges();
или для обновления данных
entities.TABLEA.Attach(entities.TABLEA.Single(t => t.NAME == TableOBJECT.NAME));
entities.TABLEA.ApplyCurrentValues(TableOBJECT);
entities.SaveChanges();
Будет ли что-нибудь из этого работать или мне нужно отслеживать, что там есть и что было добавлено?
Идеи?
Ответ №1:
Более или менее у вас уже есть решение. Вам просто нужно проверить, имеет ли ваш Single
вызов, который пытается загрузить объект из базы данных, результат или нет (используйте SingleOrDefault
вместо этого). Если в результате null
вам нужно вставить, в противном случае обновите:
foreach (var TableOBJECT in collectionOfYourTableOBJECTsTheUserWorkedWith)
{
var objectInDB = entities.TABLEA
.SingleOrDefault(t => t.NAME == TableOBJECT.NAME);
if (objectInDB != null) // UPDATE
entities.TABLEA.ApplyCurrentValues(TableOBJECT);
else // INSERT
entities.TABLEA.AddObject(TableOBJECT);
}
entities.SaveChanges();
(Я предполагаю, что NAME
это свойство первичного ключа вашей TableOBJECT
сущности.)
Комментарии:
1. Итак, в чем разница между
Single
иSingleOrDefault
?2. Single проверяет, имеет ли запрос только один результат. Если результата нет, Single выдаст исключение. SingleOrDefault проверяет один результат, если запрос пуст, он вернет значение по умолчанию (большую часть времени NULL). Поэтому используйте Single, когда всегда должен быть один результат. Используйте SingleOrDefault, когда возможно, что результата вообще нет.
3. итак, мне потребовалось некоторое время, чтобы добраться до того, где я мог бы это использовать, и это здорово, за исключением случаев, когда нужно добавить более одной вещи, я получаю исключение из базы данных, жалующееся на отсутствие уникальных ключей. Идеи?
4. @Slauma: вот исключение, которое находится в
entities.SaveChanges();
» InvalidOperationException Изменения в базе данных были успешно зафиксированы, но при обновлении контекста объекта произошла ошибка. ObjectContext может находиться в несогласованном состоянии. Сообщение о внутреннем исключении: принятие изменений не может быть продолжено, поскольку ключевые значения объекта конфликтуют с другим объектом в ObjectStateManager. Перед вызовом AcceptChanges убедитесь, что значения ключа уникальны. »5. Я изучил это исключение первого шанса, и из того, что я могу сказать, это означает, что это может вызвать исключение позже, но не только сейчас. Итак, я улавливаю это, игнорирую, и все продолжает работать нормально. Звучит ли это безопасно или я действительно должен выяснить, как это остановить?
Ответ №2:
Я думаю, вам нужно отслеживать, что нового и что изменено. Если вы это сделаете, два приведенных вами примера кода будут работать. Простой обходной путь, который я использовал, — это проверить, установлено ли для свойства первичного ключа объекта какое-либо значение. Если для него установлено значение, то это обновленный объект, в противном случае он новый.
Другим решением было бы использовать объекты самоконтроля Entity Framework, но я не думаю, что это правильное направление для веб-приложения (возможно, это в распределенном приложении WCF).