LINQ To SQL: Удалить сущность (по идентификатору) одним запросом - PullRequest
17 голосов
/ 04 декабря 2008

Я уже некоторое время работаю с LINQ To SQL, и когда дело доходит до удаления сущности из БД, я всегда вызывал таблицу .DeleteOnSubmit и передавал ее. Иногда я замечаю, что пишу что-то вроде:

db.Users.DeleteOnSubmit(db.Users.Where(c => c.ID == xyz).Select(c => c).Single());

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

Ответы [ 5 ]

5 голосов
/ 02 июля 2013

Сделайте это без использования инструментов SQL, добавив частичный объект и удалив его:

var myEntity = new MyEntityType { MyEntityId = xxx };
Context.MyEntityTypeTable.Attach(myEntity, false);
Context.MyEntityTypeTable.DeleteOnSubmit(myEntity);
Context.SubmitChanges();

Easy. Вы даже можете написать его как метод расширения и использовать динамический тип объекта для представления ключа, а также использовать отражение, чтобы выяснить ключевые свойства, которые я оставлю в качестве забавного упражнения для читателя. Например. реализовать Context.Delete (new {MyEntityId = xxx});

5 голосов
/ 04 декабря 2008

Вот решение ...

public static void DeleteByPK<TSource, TPK>(TPK pk, DataContext dc)
  where TSource : class
{
  Table<TSource> table = dc.GetTable<TSource>();
  TableDef tableDef = GetTableDef<TSource>();

  dc.ExecuteCommand("DELETE FROM [" + tableDef.TableName
    + "] WHERE [" = tableDef.PKFieldName + "] = {0}", pk);
}

Это не мой код! См. Для объяснения - http://msmvps.com/blogs/omar/archive/2008/10/30/linq-to-sql-delete-an-entity-using-primary-key-only.aspx

Надеюсь, это поможет.

0 голосов
/ 04 ноября 2011

Я знаю, что этот вопрос старый, но вот более новое и (ИМО) лучшее решение.
Я пытался сделать то же самое, когда наткнулся на PLINQO . Очень хороший набор расширений для LINQ. На этой странице описывается, как выполнять удаление с использованием методов расширения PLINQO, которые требуют только 1 приема-передачи на сервер базы данных. Недостатком является то, что для запуска требуется Codesmith , что немного дорого.

0 голосов
/ 08 декабря 2010

Я использую следующие методы расширения:

context.Customers.DeleteEntity(c => c.CustomerId, 12);

public static class EntityExtensions
{
    public static EntityKey CreateEntityKey<T, TId>(this ObjectSet<T> entitySet, Expression<Func<T, TId>> entityKey, TId id)
        where T : class
    {
        var qEntitySet = entitySet.Context.DefaultContainerName + "." + entitySet.EntitySet.Name;
        var keyName = LinqHelper.PropertyName(entityKey);

        return new EntityKey(qEntitySet, keyName, id);
    }

    public static void DeleteEntity<T, TId>(this ObjectSet<T> entitySet, Expression<Func<T, TId>> entityKey, TId id) 
        where T : EntityObject, new()
    {
        var key = CreateEntityKey(entitySet, entityKey, id);

        var entityInstance = new T {EntityKey = key};

        var propertyName = LinqHelper.PropertyName(entityKey);
        var property = typeof (T).GetProperty(propertyName);
        if (property == null)
            throw new Exception("Property name " + propertyName + " does not exist on " + typeof(T).Name);
        property.SetValue(entityInstance, id, null);

        entitySet.Attach(entityInstance);
        entitySet.DeleteObject(entityInstance);
    }
0 голосов
/ 04 декабря 2008

Я не верю, что Linq to Sql может сделать это изначально, хотя написание хранимой процедуры даст вам то, что вы хотите, с синтаксисом вроде:

db.spDeleteUserById(id);

Это потребовало бы написания хранимой процедуры для каждой таблицы, но это довольно тривиальное количество SQL.


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

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

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