Ich versuche zu ermitteln, wie zählen die übereinstimmenden Zeilen in einer Tabelle mit dem EntityFramework.Wie COUNT Zeilen innerhalb EntityFramework, ohne Inhalte zu laden?
Das Problem ist, dass jede Zeile viele Megabyte Daten (in einem binären Feld) haben kann. Natürlich wäre die SQL etwas wie folgt aus:
SELECT COUNT(*) FROM [MyTable] WHERE [fkID] = '1';
ich alle Zeilen laden konnte und dann mit dem Grafen zu finden:
var owner = context.MyContainer.Where(t => t.ID == '1');
owner.MyTable.Load();
var count = owner.MyTable.Count();
Aber das ist höchst ineffizient. Gibt es einen einfacheren Weg?
EDIT: Danke, alles. Ich habe die DB von einem privaten Anhang verschoben, damit ich Profiling ausführen kann; Das hilft aber führt zu Verwirrungen, die ich nicht erwartet habe. an und ich will nicht, dass die Truck zu verlassen, es sei denn es gibt -
Und meine realen Daten ist ein bisschen tiefer, werde ich Paletten von Hüllen von Artikel verwenden Trucks Trage mindestens eine Artikel drin.
Meine Versuche sind unten gezeigt. Der Teil, den ich nicht bekomme, 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 SQL aus CASE_1 resultiert, wird geleitet durch Sp_executesql, aber:
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 wirklich nicht haben Trucks, Treiber, Paletten, Kisten oder Gegenstände; Wie Sie aus der SQL sehen können, sind die Truck-Pallet- und Pallet-Case-Beziehungen viele-zu-viele - obwohl ich das nicht für wichtig halte. Meine realen Objekte sind immaterielle Werte und schwerer zu beschreiben, daher habe ich die Namen geändert.]
Wie haben Sie das Palettenladeproblem gelöst? – Sherlock