繁体   English   中英

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

[英]LINQ To SQL: Delete entity (by ID) with one query

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

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

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

通过附加部分对象并删除它,无需手动工具SQL即可执行此操作:

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

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

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

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

希望这可以帮助。

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

db.spDeleteUserById(id);

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


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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM