Wie führen Sie eine SQL-IN-Anweisung in LINQ to Entities (Entity Framework) durch, wenn Contains nicht unterstützt wird?

c# entity-framework linq linq-to-entities

Frage

Ich verwende LINQ to Entities (nicht LINQ to SQL) und habe Probleme beim Erstellen einer IN-Abfrage. Hier ist meine Frage im Moment:

var items = db.InventoryItem
                .Include("Kind")
                .Include("PropertyValues")
                .Include("PropertyValues.KindProperty")
                .Where(itm => valueIds.Contains(itm.ID)).ToList<InventoryItem>();

Wenn ich dies jedoch mache, wird die folgende Ausnahme ausgelöst:

LINQ to Entities erkennt die Methode 'Boolean Contains (Int64)' nicht. Diese Methode kann nicht in einen Speicherausdruck übersetzt werden.

Hat jemand einen Workaround oder eine andere Lösung dafür?

Akzeptierte Antwort

Sie müssen entweder dieses verwenden:

.Where(string.Format("it.ID in {0}", string.Join(",", valueIds.ToArray())));

oder konstruiere den WHERE-Teil wie in diesem Beitrag dynamisch.

PS - Informationen wurden aktualisiert und diese Antwort wurde wie folgt aktualisiert, um die Relevanz zu erhalten:

Der Link, auf den verwiesen wird, enthält das folgende Update:

... In EF4 haben wir Unterstützung für die Contains-Methode und zumindest in diesem speziellen Fall für Parameter mit Collection- Werten hinzugefügt . Daher ist diese Art von Code jetzt sofort einsatzbereit und es ist nicht notwendig, eine zusätzliche Methode zum Erstellen von Ausdrücken einzusetzen:

var statusesToFind = new List<int> {1, 2, 3, 4};
var foos = from foo in myEntities.Foos
           where statusesToFind.Contains(foo.Status)
           select foo;

Beliebte Antwort

In einigen Fällen können Sie dazu die Any Erweiterungsmethode von Linq verwenden:

var userIds = new[] { 1, 2, 3 };

from u in Users
     where userIds.Any(i => i==u.Id)
     select u;

Das generierte SQL sieht in einem solchen Fall ziemlich seltsam aus, aber wie viele von Linq-to-Entities generierte SQL ist es für einen Menschen möglicherweise zu ausführlich, jedoch in der Praxis schnell.

SELECT 
[Extent1].[Id] AS [Id], 
[Extent1].[DisplayName] AS [DisplayName], 
FROM [dbo].[Users] AS [Extent1]
WHERE  EXISTS (SELECT 
    1 AS [C1]
    FROM  (SELECT 
        [UnionAll1].[C1] AS [C1]
        FROM  (SELECT 
            1 AS [C1]
            FROM  ( SELECT 1 AS X ) AS [SingleRowTable1]
        UNION ALL
            SELECT 
            2 AS [C1]
            FROM  ( SELECT 1 AS X ) AS [SingleRowTable2]) AS [UnionAll1]
    UNION ALL
        SELECT 
        3 AS [C1]
        FROM  ( SELECT 1 AS X ) AS [SingleRowTable3]) AS [UnionAll2]
    WHERE [UnionAll2].[C1] = [Extent1].[Id]
)


Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum