2008-12-03 2 views
17

Ich arbeite seit einiger Zeit mit LINQ To SQL, und wenn es darum geht, eine Entität aus der Datenbank zu entfernen, habe ich immer die Tabelle aufgerufen. DeleteOnSubmit und in der Entität übergeben. Manchmal habe ich selbst etwas geschrieben wie:LINQ To SQL: Löschen von Entitäten (nach ID) mit einer Abfrage

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

Dies führt natürlich zu zwei Abfragen. Eine, um die Entität zu erhalten, die den Kriterien entspricht, und eine andere, um sie zu löschen. Oft habe ich die ID des Datensatzes, den ich entfernen muss, und ich frage mich, ob es eine direktere Möglichkeit gibt, eine Zeile aus einer Tabelle nur über die ID zu entfernen?

Antwort

0

Ich glaube nicht, Linq to Sql dies nativ tun können, obwohl eine gespeicherte Prozedur schreiben würden Sie geben, was Sie wollen, mit Syntax wie:

db.spDeleteUserById(id); 

Dies würde requre für jede Tabelle eine gespeicherte Prozedur schreiben , aber es ist eine ziemlich triviale Menge an SQL.


Check out this blog post, in dem der Autor eine Erweiterungsmethode erstellt hat, der seine eigene Lösch Anweisung generiert. Sie können dieses Konzept möglicherweise verwenden und damit eine Löschroutine erstellen, für die keine Auswahl erforderlich ist. Der Nachteil ist, dass Sie möglicherweise eine Erweiterungsmethode erhalten, die für Ihr eigenes Schema spezifisch ist.

Ich verstehe, dass Sie Ihre Logik aus der Datenbank-Ebene halten wollen, aber in diesem Fall denke ich, es wäre viel einfacher, die gespeicherte Proc Route zu gehen. Es würde nicht den Problemen mit einer eng gekoppelten Datenzugriffslogik ausgesetzt sein, da das Löschen einer Zeile nach ID wahrscheinlich nie ein Refactoring benötigt. Hier

6

ist eine Lösung ...

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

Es ist nicht mein Code! Siehe zur Erläuterung - http://msmvps.com/blogs/omar/archive/2008/10/30/linq-to-sql-delete-an-entity-using-primary-key-only.aspx

Hoffe das hilft.

+0

Sie könnten DeleteByPK auch zu einer Erweiterungsmethode für DataContext machen, und die Zeichenfolge selbst sollte wahrscheinlich eine parametrisierte Abfrage sein (exec sp_executesql ...). –

+7

in Zeile SQL auf einer Linq2Sql-Anweisung scheint den Zweck zu besiegen –

+3

@ Bobby: nicht wirklich.Ich verwende in Zeile SQL für die Leistung und bei Bedarf (komplexe SQL). Ruhe bei SQL-Generierung für allgemeine Operationen. –

0

ich die folgenden Erweiterungsmethoden verwenden, die Nutzung Wesen:

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

Ich weiß, diese Frage ist alt, aber hier ist eine neue und (IMO) bessere Lösung.
Ich versuchte das Gleiche zu erreichen, als ich über PLINQO lief. Sehr schöne Reihe von Erweiterungen zu LINQ. This page beschreibt, wie Löschungen mit PLINQO-Erweiterungsmethoden durchgeführt werden, die nur 1 Roundtrip zum Datenbankserver erfordern.
Der Nachteil ist, dass es erfordert Codesmith zu laufen, die ein wenig teuer ist.

4

dies ohne SQL Handwerkzeug Sie, indem Sie einen Teil-Objekt und Einstellen löschen:

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

Einfach. Sie können es sogar als eine Erweiterungsmethode schreiben und einen dynamischen Objekttyp verwenden, um den Schlüssel darzustellen, und Reflektion verwenden, um Schlüsseleigenschaften herauszufinden, die ich als eine lustige Übung für den Leser hinterlassen werde. Z.B. implementieren Context.Delete (new {MyEntityId = xxx});