簡體   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