Estoy tratando de determinar cómo contar las filas coincidentes en una tabla usando EntityFramework.
El problema es que cada fila puede tener muchos megabytes de datos (en un campo binario). Por supuesto, el SQL sería algo como esto:
SELECT COUNT(*) FROM [MyTable] WHERE [fkID] = '1';
Podría cargar todas las filas y luego encontrar el Conde con:
var owner = context.MyContainer.Where(t => t.ID == '1');
owner.MyTable.Load();
var count = owner.MyTable.Count();
Pero eso es tremendamente ineficiente. ¿Hay alguna forma más simple?
EDITAR: Gracias a todos. He movido la base de datos de un adjunto privado para poder ejecutar la creación de perfiles; esto ayuda pero causa confusiones que no esperaba.
Y mis datos reales son un poco más profundos, usaré camiones que transporten paletas de cajas de artículos , y no quiero que el camión se vaya a menos que haya al menos un artículo en él.
Mis intentos se muestran a continuación. La parte que no entiendo es que CASE_2 nunca accede al servidor de base de datos (MSSQL).
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
Y el SQL resultante de CASE_1 se canaliza a través de sp_executesql , pero:
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
[ Realmente no tengo camiones, conductores, tarimas, cajas o artículos; Como puede ver en el SQL, las relaciones Camión-Palé y Palé-Caja son de muchos a muchos, aunque no creo que eso importe. Mis objetos reales son intangibles y más difíciles de describir, así que cambié los nombres. ]