Как удалить объект из модели Entity Framework без предварительной загрузки? - PullRequest
39 голосов
/ 02 февраля 2009

Я совершенно уверен, что где-то видел ответ на этот вопрос, но так как я не смог найти его с помощью пары запросов в SO или Google, я все равно спрашиваю его ...

В Entity Framework единственным способом удаления объекта данных является

MyEntityModel ent = new MyEntityModel();
ent.DeleteObject(theObjectToDelete);
ent.SaveChanges();

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

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

Ответы [ 7 ]

19 голосов
/ 14 июня 2010

Стоит знать, что Entity Framework поддерживает как Linq to Entities, так и Entity SQL. Если вы обнаружите, что хотите делать удаления или обновления, которые могут повлиять на многие записи, вы можете использовать эквивалент ExecuteNonQuery.

В Entity SQL это может выглядеть как

   Using db As New HelloEfEntities

        Dim qStr = "Delete " & _
                  "FROM Employee"
        db.ExecuteStoreCommand(qStr)
        db.SaveChanges()
    End Using

В этом примере db - это мой ObjectContext. Также обратите внимание, что функция ExecuteStoreCommand принимает необязательный массив параметров.

8 голосов
/ 02 февраля 2009

Я нашел это сообщение , в котором говорится, что действительно нет лучшего способа удалить записи. Было дано объяснение, что все внешние ключи, отношения и т. Д., Которые являются уникальными для этой записи, также удаляются, и поэтому EF должна иметь правильную информацию о записи. Я озадачен, почему этого нельзя достичь без загрузки данных туда-сюда, но так как этого не случится очень часто, я решил (пока), что не буду беспокоиться.

Если у вас есть решение этой проблемы, не стесняйтесь, дайте мне знать =)

4 голосов
/ 14 июня 2016

Вы можете создать объект с тем же идентификатором и передать его на удаление. НО это хорошо для простых объектов, если у вас сложные отношения, вам может понадобиться больше, чем

                var user = new User { ID = 15 };
                context.Entry(user).State = EntityState.Deleted;
                context.SaveChanges();
4 голосов
/ 11 февраля 2009

Есть способ подменить загрузку объекта путем пересчета его EntityKey. Это похоже на взлом, но, возможно, это единственный способ сделать это в EF.

Статья в блоге Удаление без извлечения

4 голосов
/ 02 февраля 2009

Извиняюсь заранее, но я должен поставить под сомнение вашу цель.

Если вы удалите объект, даже не прочитав его, то вы не сможете узнать, изменил ли этот объект другой пользователь в промежуток времени между подтверждением того, что вы хотите удалить объект, и фактическим удалением. В «простом старом SQL» это будет выглядеть так:

DELETE FROM FOO
WHERE ID = 1234

Конечно, большинство людей на самом деле не делают этого. Вместо этого они делают что-то вроде:

DELETE FROM FOO
WHERE ID = 1234
  AND NAME = ?ExpectedName AND...

Дело в том, что удаление должно завершиться неудачей (ничего не делать), если другой пользователь изменил запись за это время.

С этим, лучшим изложением проблемы, есть два возможных решения при использовании Entity Framework.

  1. В вашем методе Delete, существующем экземпляре, сравните ожидаемые значения свойств и удалите, если они совпадают. В этом случае Entity Framework позаботится о написании оператора DELETE, который включает значения свойств.

  2. Напишите хранимую процедуру, которая принимает как IDE, так и другие значения свойств, и выполните это.

3 голосов
/ 23 июля 2013

В Entity Framework 5 есть Расширенная библиотека Entity Framework . Доступно на NuGet. Тогда вы можете написать что-то вроде:

context.Users.Delete(u => u.Id == id);

Это также полезно для массового удаления.

3 голосов
/ 08 мая 2013
var toDelete = new MyEntityModel{
    GUID = guid,
    //or ID = id, depending on the key
    };
Db.MyEntityModels.Attach(toDelete);
Db.MyEntityModels.DeleteObject(toDelete);
Db.SaveChanges();

Если ваш ключ содержит несколько столбцов, необходимо указать все значения (например, GUID, columnX, columnY и т. Д.).

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

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