Обновить запись без предварительного запроса?

Предположим, что я запрашиваю базу данных и загружаю список элементов. Затем я открываю один из элементов в форме подробного представления, и вместо повторного запроса элемента из базы данных я создаю экземпляр элемента из источника данных в списке.

Есть ли способ обновить запись базы данных, не извлекая запись отдельного элемента?

Вот пример, как я это делаю сейчас:

dataItem itemToUpdate = (from t in dataEntity.items
                                 where t.id == id
                                 select t).FirstOrDefault();

Затем, потянув за запись, я обновляю некоторые значения в элементе и нажимаю запись:

itemToUpdate.itemstatus = newStatus;
dataEntity.SaveChanges();

Я бы подумал, что будет лучший способ сделать это, любые идеи?

Ответ 2

Вы также можете использовать прямой SQL для базы данных, используя контекст хранилища данных. Пример:

dataEntity.ExecuteStoreCommand
   ("UPDATE items SET itemstatus = 'some status' WHERE id = 123 ");

По соображениям производительности вам может потребоваться передать переменные вместо одной жестко закодированной строки SQL. Это позволит SQL Server кэшировать запрос и повторно использовать его с параметрами. Пример:

dataEntity.ExecuteStoreCommand
   ("UPDATE items SET itemstatus = 'some status' WHERE id = {0}", new object[] { 123 });

UPDATE - для EF 6.0

dataEntity.Database.ExecuteSqlCommand
       ("UPDATE items SET itemstatus = 'some status' WHERE id = {0}", new object[] { 123 });

Ответ 3

Если в элементе DataItem есть поля EF, которые будут предварительно проверяться (например, поля с непустым значением), нам придется отключить эту проверку для этого контекста:

DataItem itemToUpdate = new DataItem { Id = id, Itemstatus = newStatus };
dataEntity.Entry(itemToUpdate).Property(x => x.Itemstatus).IsModified = true;
dataEntity.Configuration.ValidateOnSaveEnabled = false;
dataEntity.SaveChanges();
//dataEntity.Configuration.ValidateOnSaveEnabled = true;

В противном случае мы можем попробовать выполнить предварительную проверку и по-прежнему обновлять только один столбец:

DataItem itemToUpdate = new DataItem
{
    Id = id,
    Itemstatus = newStatus,
    NonNullableColumn = "this value is disregarded - the db original will remain"
};
dataEntity.Entry(itemToUpdate).Property(x => x.Itemstatus).IsModified = true;
dataEntity.SaveChanges();

Предполагая, что dataEntity есть System.Data.Entity.DbContext

Вы можете проверить запрос, сгенерированный добавлением этого параметра в DbContext:

/*dataEntity.*/Database.Log = m => System.Diagnostics.Debug.Write(m);

Ответ 4

Код:

ExampleEntity exampleEntity = dbcontext.ExampleEntities.Attach(new ExampleEntity { Id = 1 });
exampleEntity.ExampleProperty = "abc";
dbcontext.Entry<ExampleEntity>(exampleEntity).Property(ee => ee.ExampleProperty).IsModified = true;
dbcontext.Configuration.ValidateOnSaveEnabled = false;
dbcontext.SaveChanges();

Результат TSQL:

exec sp_executesql N'UPDATE [dbo].[ExampleEntities]
SET [ExampleProperty ] = @0
WHERE ([Id] = @1)
',N'@0 nvarchar(32),@1 bigint',@0='abc',@1=1

Примечание:

Строка IsModified = true необходима, потому что, когда вы создаете новый объект ExampleEntity (только при заполнении свойства Id), все остальные свойства имеют свои значения по умолчанию (0, null и т.д.). Если вы хотите обновить БД "значением по умолчанию", это изменение не будет обнаружено инфраструктурой сущностей, а затем БД не будет обновляться.

В примере:

exampleEntity.ExampleProperty = null;

не будет работать без строки "IsModified = true", потому что свойство ExampleProperty уже имеет значение null, когда вы создали пустой объект ExampleEntity, вам нужно сказать EF, что этот столбец должен быть обновлен, и это цель эта строка.

Ответ 5

Эта статья как часть Microsoft Getting Started объясняет состояния сущностей и как это сделать:

Добавить/Прикрепить и сущности >

Посмотрите на раздел "Присоединение существующего, но измененного объекта к контексту"

Теперь я прошу прочесть оставшиеся уроки.

Ответ 6

Вообще говоря, если вы использовали Entity Framework для запроса всех элементов и сохранили объект сущности, вы можете обновить отдельные элементы объекта сущности и вызвать SaveChanges() по завершении. Например:

var items = dataEntity.Include("items").items;
// For each one you want to change:
items.First(item => item.id == theIdYouWant).itemstatus = newStatus;
// After all changes:
dataEntity.SaveChanges();

Поиск одного элемента, который вы хотите, не должен генерировать новый запрос.