Como los datos de carga de hermanos deseosos utilizando LINQ a SQL?
-
23-09-2019 - |
Pregunta
El objetivo es emitir los menor número de consultas a SQL Server mediante LINQ a SQL sin necesidad de utilizar los tipos anónimos. El tipo de retorno para el método tendrá que ser IList
Parent
Child1 Child2
Grandchild1
Padres> Niño1 es una relación de uno a muchos
Niño1> Grandchild1 es un uno-a-n relación (donde n es cero a infinito)
Padres> Niño2 es un uno-a-n relación (donde n es cero a infinito)
Soy capaz de cargar con ganas de Padres, los datos child1 y Grandchild1 lo que resulta en una consulta a SQL Server.
Esta consulta con todas las opciones de carga de los datos de cargas ansiosos, con excepción de los datos de hermanos (Niño2):
DataLoadOptions loadOptions = new DataLoadOptions();
loadOptions.LoadWith<Child1>(o => o.GrandChild1List);
loadOptions.LoadWith<Child1>(o => o.Parent);
dataContext.LoadOptions = loadOptions;
IQueryable<Child1> children = from child in dataContext.Child1
select child;
Es necesario cargar los datos de hermanos también. Uno de los enfoques que he probado es dividir la consulta en dos LINQ a las consultas SQL y la fusión de los conjuntos de resultados en conjunto (no muy), sin embargo, al acceder a los datos de hermanos es de todos modos cargado perezoso.
La adición de la opción de carga de hermanos emitirá una consulta a SQL Server para cada registro Grandchild1 y Niño2 (que es exactamente lo que estoy tratando de evitar):
DataLoadOptions loadOptions = new DataLoadOptions();
loadOptions.LoadWith<Child1>(o => o.GrandChild1List);
loadOptions.LoadWith<Child1>(o => o.Parent);
loadOptions.LoadWith<Parent>(o => o.Child2List);
dataContext.LoadOptions = loadOptions;
IQueryable<Child1> children = from child in dataContext.Child1
select child;
exec sp_executesql N'SELECT * FROM [dbo].[Child2] AS [t0]
WHERE [t0].[ForeignKeyToParent] = @p0',N'@p0 int',@p0=1
exec sp_executesql N'SELECT * FROM [dbo].[Child2] AS [t0]
WHERE [t0].[ForeignKeyToParent] = @p0',N'@p0 int',@p0=2
exec sp_executesql N'SELECT * FROM [dbo].[Child2] AS [t0]
WHERE [t0].[ForeignKeyToParent] = @p0',N'@p0 int',@p0=3
exec sp_executesql N'SELECT * FROM [dbo].[Child2] AS [t0]
WHERE [t0].[ForeignKeyToParent] = @p0',N'@p0 int',@p0=4
LINQ También he escrito a las consultas SQL a participar en todos los datos con la esperanza de que lo haría con ganas de carga de los datos, sin embargo, cuando el LINQ a SQL EntitySet de Niño2 o Grandchild1 que se accede a los datos de las cargas perezosos.
La razón de volver la IList
Mis pensamientos están Estoy bien:
- abordar este problema de manera equivocada.
- tiene la opción de llamar a un procedimiento almacenado?
- Mi organización no debería estar utilizando LINQ a SQL como un ORM?
Cualquier ayuda es muy apreciada.
Gracias,
-Scott
Solución
Lo que tienes debe ser correcta, es necesario añadir este dataContext.DeferredLoadingEnabled = false;
además de los LoadOptions que ya está configurando.
Otros consejos
var children2 = from child2 in dataContext.Child2
where children.Any(c1 => c1.Parent == child2.Parent)
select child2;
En caso de resultar en una sola consulta existe, por lo que va a terminar siendo dos consultas.