2017-06-15 3 views
0

Ich versuche, die außer Methode zu bekommen wie in dieser Antwort zu arbeiten: https://stackoverflow.com/a/3944821/169714zur Entfernung Sammlung ausschließen, Linq

1. Versuch:

var housesToRemove = db.Houses.Except(houses).ToList(); 

2. Versuch:

var housesToRemove = db.Houses.Where(h => 
    !houses.Any(h2 => h2.Code.Equals(h.Code) && h2.OperatorId == h.OperatorId)).ToList(); 

Meine Houses-Klasse hat Vorrang. Entspricht:

public override bool Equals(object obj) 
{ 
    var item = obj as House; 

    if (item == null) 
     return false; 

    return this.Code == item.Code && this.OperatorId == item.OperatorId; 
} 

public override int GetHashCode() 
{ 
    return this.ID.GetHashCode(); 
} 

beiden Optionen werfen:

System.NotSupportedException: ‚Es kann keine konstanten Wert des Typs schaffen 'Haus'. In diesem Kontext werden nur primitive Typen oder Aufzählungstypen unterstützt.

Teil des Codes, wo ich es verwenden:

using (var db = new HouseContext()) 
{ 
    var housesToRemove = db.Houses.Where(h => !houses.Any(h2 => h2.Code.Equals(h.Code) && h2.OperatorId == h.OperatorId)).ToList(); 

    foreach (var htr in housesToRemove) 
    { 
     Console.WriteLine(htr); // I have also overwritten ToString() from House 
    } 
    housesToRemove.ForEach(x => x.IsListed = false); 
    db.SaveChanges(); 
} 

Antwort

1

Die Frage, die Sie verknüpft haben, ist mit Linq to Entities und Sie verwenden Linq to SQL, die bedeutet, dass Ihre Except Abfrage wird an die Datenbank gesendet. Die Datenbank hat keine Vorstellung davon, was Sie eigentlich hier machen wollen.

Ich würde empfehlen, die Antwort hier zu folgen: https://stackoverflow.com/a/18944508/639771 für weitere Informationen darüber, warum dies fehlschlägt, sowie wie Sie umgehen.

tl; dr

Sie versuchen, im Speicher vergleichen Objekte auf Datenbankobjekte, wie die SQL-Engine einen Dreck nicht geben über Ihre Equals überschreiben, alles was man sieht, ist ein in -memory House-Objekt und ein Aufruf an die Datenbank, dass es irgendwie über den Vergleich möglich sein muss. Sie könnten stattdessen die IDs der Häuser heben Sie nicht wollen, und so etwas wie:

var ids = houses.Select(h => h.Id).ToArray(); 
var filtered = db.Houses.Where(h => !ids.Contains(h.Id)).ToList(); 
+0

Dank, dachte ich, dass Linq (db.Houses) eine interne Liste von allem, was in Erinnerung hatte. –

+0

@JPellemons Nein, es ist tatsächlich viel verrückter. Es basiert alles auf 'IQueryable', das die LINQ-Ausdrücke übernimmt und sie in SQL-Anweisungen übersetzt und dann an die Datenbank absetzt. So können Sie in einer Tabelle mit Millionen von Zeilen suchen, ohne zuerst alle Daten laden zu müssen. – Clint

Verwandte Themen