2010-03-30 15 views
16

El objetivo es emitir el menos consultas a SQL Server utilizando LINQ to SQL sin usar tipos anónimos. El tipo de devolución para el método deberá ser IList <Child1>. Las relaciones son las siguientes:¿Cómo ansioso cargar datos de hermanos usando LINQ to SQL?

  Parent 
    Child1   Child2 
Grandchild1 

Parent> Niño1 es una relación de uno a muchos

Niño1> Grandchild1 una relación uno-a-n (donde n es cero a infinito)

Padres> Niño2 es una relación uno-a-n (donde n es cero a infinito)

soy aBL e a impaciente cargar los datos Parent, Child1 y Grandchild1 dando como resultado una consulta a SQL Server.

Esta consulta con opciones de carga cargas deseosos todos de los datos, excepto los datos de hermanos (CHILD2):

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; 

necesito para cargar los datos de hermanos también. Un enfoque que he intentado es dividir la consulta en dos consultas de LINQ a SQL y combinar los conjuntos de resultados (no muy), sin embargo, al acceder a los datos de los hermanos, se carga de todos modos.

Añadiendo 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 

También he escrito LINQ a las consultas SQL para unir todos los datos con la esperanza de que estaría ansioso por cargar los datos, sin embargo, cuando se accede al LINQ to SQL EntitySet de Child2 o Grandchild1, se carga de forma lenta los datos.

El motivo de devolver el IList <Child1> es para hidratar objetos comerciales.

Mis pensamientos están Estoy bien:

  1. abordar este problema de manera equivocada.
  2. ¿Tiene la opción de llamar a un procedimiento almacenado?
  3. Mi organización no debería usar LINQ to SQL como ORM?

Cualquier ayuda es muy apreciada.

Gracias,

-Scott

+0

Fuera de interés, ¿por qué no quieres utilizar tipos anónimos o algún tipo de contenedor? – SteadyEddi

Respuesta

14

Lo que tienes debe ser correcta, es necesario añadir este dataContext.DeferredLoadingEnabled = false; además de los LoadOptions que ya está configurando.

+0

Esta sugerencia funcionó para mí. Pude obtener los datos de hermanos de Child2 en una segunda consulta utilizando el mismo contexto de datos. Al establecer DeferredLoadingEnabled en false, pude fusionar el conjunto de resultados de Child2 con la primera consulta sin intentar cargar un conjunto de entidades antes de poder establecer los datos. Si alguien tiene otras ideas para la recuperación, también agradecería esas sugerencias. Gracias Nate. – Scott

0
var children2 = from child2 in dataContext.Child2 
       where children.Any(c1 => c1.Parent == child2.Parent) 
       select child2; 

Debe dar como resultado una sola consulta existente, por lo que terminará siendo dos consultas.