LINQ To SQL:使用一个查询删除实体(按ID)

时间:2008-12-03 22:52:54

标签: c# sql linq

我一直在使用LINQ To SQL一段时间,当涉及从数据库中删除实体时,我总是调用表的.DeleteOnSubmit并传入实体。有时我发现自己写的是:

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

这当然导致两个查询。一个用于获取符合条件的实体,另一个用于删除它。通常我有我需要删除的记录的ID,我想知道是否有更直接的方法通过ID从表中删除行?

5 个答案:

答案 0 :(得分:5)

这是一个解决方案......

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

希望这有帮助。

答案 1 :(得分:5)

通过附加部分对象并删除它来不用手工工具SQL来执行此操作:

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

易。您甚至可以将其作为扩展方法编写,并使用动态对象类型来表示键,并使用反射来确定关键属性,我将留给读者作为有趣的练习。例如。实现Context.Delete(new {MyEntityId = xxx});

答案 2 :(得分:0)

我不相信Linq to Sql可以原生这样做,虽然编写存储过程会给你你想要的东西,语法如下:

db.spDeleteUserById(id);

这将要求为每个表编写一个存储过程,但这是一个非常微不足道的SQL。


查看this blog post,作者在其中创建了一个生成自己的删除语句的扩展方法。您可以采用此概念并使用它来创建不需要select的删除例程。缺点是,您最终可能会使用特定于您自己架构的扩展方法。

我知道您希望将逻辑排除在数据库层之外,但在这种情况下,我认为将存储过程路由更简单。它不会受到紧耦合数据访问逻辑的影响,因为按id删除行不太可能需要重构。

答案 3 :(得分:0)

我使用以下扩展方法,用法为:

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);
    }

答案 4 :(得分:0)

我知道这个问题已经过时了,但这是一个更新的(IMO)更好的解决方案 当我跑过PLINQO时,我试图完成同样的事情。对LINQ非常好的扩展。 This page描述了如何使用PLINQO的扩展方法执行删除操作,这些方法只需要向数据包服务器进行1次往返。
缺点是它需要运行Codesmith,这有点贵。