Wie ZÄHLEN Sie Zeilen in EntityFramework, ohne Inhalte zu laden?

c# database entity-framework

Frage

Ich versuche , um zu bestimmen , wie die passenden Zeilen auf einem Tisch zu zählen , die EntityFramework verwenden.

Das Problem ist, dass jede Zeile viele Megabytes an Daten enthalten kann (in einem binären Feld). Natürlich würde die SQL so aussehen:

SELECT COUNT(*) FROM [MyTable] WHERE [fkID] = '1';

Ich könnte alle Zeilen laden und finde dann den Count mit:

var owner = context.MyContainer.Where(t => t.ID == '1');
owner.MyTable.Load();
var count = owner.MyTable.Count();

Das ist aber völlig ineffizient. Gibt es einen einfacheren Weg?


EDIT: Danke, alle. Ich habe die Datenbank aus einem privaten Ordner verschoben, damit ich die Profilerstellung ausführen kann. das hilft aber verwirrungen, die ich nicht erwartet hätte.

Und meine wirklichen Daten sind etwas tiefer, ich verwende LKWs, die Paletten mit Kisten mit Gegenständen transportieren - und ich möchte nicht, dass der Lastwagen abfährt, wenn nicht mindestens ein Gegenstand darin ist.

Meine Versuche werden unten gezeigt. Der Teil, den ich nicht verstehe, ist, dass CASE_2 niemals auf den DB-Server (MSSQL) zugreift.

var truck = context.Truck.FirstOrDefault(t => (t.ID == truckID));
if (truck == null)
    return "Invalid Truck ID: " + truckID;
var dlist = from t in ve.Truck
    where t.ID == truckID
    select t.Driver;
if (dlist.Count() == 0)
    return "No Driver for this Truck";

var plist = from t in ve.Truck where t.ID == truckID
    from r in t.Pallet select r;
if (plist.Count() == 0)
    return "No Pallets are in this Truck";
#if CASE_1
/// This works fine (using 'plist'):
var list1 = from r in plist
    from c in r.Case
    from i in c.Item
    select i;
if (list1.Count() == 0)
    return "No Items are in the Truck";
#endif

#if CASE_2
/// This never executes any SQL on the server.
var list2 = from r in truck.Pallet
        from c in r.Case
        from i in c.Item
        select i;
bool ok = (list.Count() > 0);
if (!ok)
    return "No Items are in the Truck";
#endif

#if CASE_3
/// Forced loading also works, as stated in the OP...
bool ok = false;
foreach (var pallet in truck.Pallet) {
    pallet.Case.Load();
    foreach (var kase in pallet.Case) {
        kase.Item.Load();
        var item = kase.Item.FirstOrDefault();
        if (item != null) {
            ok = true;
            break;
        }
    }
    if (ok) break;
}
if (!ok)
    return "No Items are in the Truck";
#endif

Und die aus CASE_1 resultierende SQL wird über sp_executesql geleitet , jedoch:

SELECT [Project1].[C1] AS [C1]
FROM   ( SELECT cast(1 as bit) AS X ) AS [SingleRowTable1]
LEFT OUTER JOIN  (SELECT 
    [GroupBy1].[A1] AS [C1]
    FROM ( SELECT 
        COUNT(cast(1 as bit)) AS [A1]
        FROM   [dbo].[PalletTruckMap] AS [Extent1]
        INNER JOIN [dbo].[PalletCaseMap] AS [Extent2] ON [Extent1].[PalletID] = [Extent2].[PalletID]
        INNER JOIN [dbo].[Item] AS [Extent3] ON [Extent2].[CaseID] = [Extent3].[CaseID]
        WHERE [Extent1].[TruckID] = '....'
    )  AS [GroupBy1] ) AS [Project1] ON 1 = 1

[ Ich habe nicht wirklich Lastwagen, Fahrer, Paletten, Koffer oder Gegenstände; Wie Sie aus der SQL sehen können, sind die Beziehungen zwischen Truck-Pallet und Pallet-Case viele zu viele - obwohl ich glaube, dass das keine Rolle spielt. Meine wahren Objekte sind immaterielle Güter und schwieriger zu beschreiben, daher änderte ich die Namen. ]

Akzeptierte Antwort

Abfragesyntax:

var count = (from o in context.MyContainer
             where o.ID == '1'
             from t in o.MyTable
             select t).Count();

Methodensyntax:

var count = context.MyContainer
            .Where(o => o.ID == '1')
            .SelectMany(o => o.MyTable)
            .Count()

Beide generieren dieselbe SQL-Abfrage.


Beliebte Antwort

Ich glaube du willst so etwas

var count = context.MyTable.Count(t => t.MyContainer.ID == '1');

(bearbeitet, um Kommentare zu reflektieren)



Related

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