2009-06-16 21 views
12

Tengo problemas para vincular un telerik RadGrid y un simple GridView de ASP.NET con los resultados de la siguiente consulta de LINQ a entidades. En ambos casos, las cuadrículas contienen el número correcto de filas, pero los datos de solo el primer puñado de filas se duplican en todas las otras filas. Estoy asignando directamente el valor de retorno de este código a la propiedad DataSource en las cuadrículas.Filas duplicadas cuando se vinculan datos con LINQ a Entidades

public IEnumerable<DirectoryPersonEntry> FindPersons(string searchTerm) 
{ 
    DirectoryEntities dents = new DirectoryEntities(); 
    return from dp in dents.DirectoryPersonEntrySet 
      where dp.LastName.StartsWith(searchTerm) || dp.Extension.StartsWith(searchTerm) 
      orderby dp.LastName, dp.Extension 
      select dp; 
} 

añadido: Este es el código ADO.NET llanura alternativo que funciona:

DataTable ret = new DataTable(); 
    using (SqlConnection sqn = new SqlConnection(ConfigurationManager.ConnectionStrings["WaveAdo"].ConnectionString)) 
    { 
     SqlDataAdapter adap = new SqlDataAdapter("select * from DirectoryPersonList where LastName like '" + searchTerm + "%' order by LastName ", sqn); 
     sqn.Open(); 
     adap.Fill(ret); 
    } 
    return ret; 

MÁS:

  1. La consulta enviada a SQL Server mediante LINQ funciona.
  2. Al iterar los resultados de la consulta LINQ antes de devolverlos se obtienen las mismas duplicaciones.
  3. Al iterar los resultados de LINQ en el método de llamada, antes de enlazar, se producen las mismas duplicaciones.

ACTUALIZACIÓN: Basándose en el asesoramiento muy lógico y apropiado de Marc Gravel a continuación, he encontrado que el diseñador de EF había hecho una suposición muy ignorante en una clave de entidad para mi clase de entidad, el primer campo en su lista de campos, departamento, del cual solo hay siete entradas compartidas en todos los demás registros.

Esto es de hecho la causa de la duplicación. Si tan solo pudiera cambiar o eliminar la clave de entidad, pero este diseñador EF con toda la lógica de negocios de un Etch-a-Sketch está admirablemente comprometido a repetir su elección retrasada de clave mientras se ríe de mí bloqueado afuera pidiendo cambiar la clave.

+0

¿Estás seguro de que la tabla no contiene duplicados? La consulta es correcta –

+0

@ Alexander, sí, estoy seguro. Una consulta simple de DataTable en la misma vista da como resultado que las cuadrículas se vinculen correctamente. – ProfK

+0

Por favor, muestre más código. Ambos trabajando y problemático. –

Respuesta

30

Me parece que tiene una clave principal en borked. El aspecto de "gestión de identidad" de LINQ-to-SQL y EF significa que está obligado a devolverle la misma instancia siempre que vea los mismos valores de clave principal para el mismo tipo de objeto.

Por ejemplo, dados los datos:

id  | name  | ... 
-------+------------+------ 
1  | Fred  | ... 
2  | Barney  | ... 
1  | Wilma  | ... 
1  | Betty  | ... 

Entonces si se piensa id es una clave principal cuando se itera sobre los objetos de LINQ, es obligados para darle "Fred", " Barney "," Fred "," Fred ". Básicamente, cuando ve id 1 de nuevo, ni siquiera mira a las otras columnas, simplemente busca la instancia con id 1 desde la caché de identidad y le da la misma instancia de Fred que le dio anteriormente. Si no es piensa que id es una clave principal, tratará cada fila como un objeto separado (y entonces, ¿qué pasa si tiene el mismo valor en uno de los campos que otro registro? Eso no es exactamente inusual).

Recomendaría comprobar que los campos que ha marcado como clave principal (en su modelo DBML/EDM) sean realmente únicos por fila.En el caso anterior, la columna id claramente no representa un identificador único, por lo que no es adecuada como clave principal. Simplemente desmarquelo como tal en el diseñador LINQ-to-SQL/EF.


actualización en particular, ver la propiedad "Entidad clave" para las distintas propiedades en el diseñador - sobre todo si se está consultando una vista. Verifique que "Clave de entidad" solo esté configurada en verdadero para las columnas adecuadas (es decir, aquellas que hacen que la fila sea única). Si está configurado incorrectamente, establézcalo en falso. Esto también es visible como el ícono de la tecla amarilla: esto solo debería aparecer en cosas que son genuinamente identificadores únicos para un registro.

+3

+1 para usar borked. También buena respuesta. –

+0

@Marc, gran cosa, identificaste el problema con mayor precisión. Sin embargo, sugieres simplemente eliminar el indicador de clave de entidad de la columna de problema, pero no puedo hacerlo. – ProfK

+0

Puedo cambiar la clave de entidad para el conjunto de entidades, pero no para la tabla, por lo que las asignaciones se 'borked'. – ProfK

1

Y si ajusta la consulta de enlace entre paréntesis y utiliza la extensión .Distinct()?

public IEnumerable<DirectoryPersonEntry> FindPersons(string searchTerm) 
{ 
    DirectoryEntities dents = new DirectoryEntities(); 
    return (from dp in dents.DirectoryPersonEntrySet 
      where dp.LastName.StartsWith(searchTerm) || dp.Extension.StartsWith(searchTerm) 
      orderby dp.LastName, dp.Extension 
      select dp).Distinct(); 
} 
+0

Eso me da resultados aún más extraños, con duplicados similares, pero un conjunto diferente de entradas que se ajustan a los mismos criterios. Voy a bloguear las diferencias. – ProfK

0

Una diferencia entre sus consultas de trabajo y las quebradas es la cláusula orderby. Encontré un documented bug en el pedido por implementación en Linq a Entidades ... puede haber otras.

Intente eliminar el orden de la consulta errónea y vea si todavía obtiene duplicados.

Otra diferencia es el OR en la cláusula where. Intente usar solo la primera parte [donde dp.LastName.StartsWith (searchTerm)] y vea si aún obtiene duplicados.

0

Me enfrenté al mismo problema y lo resolví con una solución alternativa. Lo estoy publicando aquí, ya que podría ayudar a otros a venir aquí.

lugar de select dp, utilice

select new <ObjectName> 
{ 
a = v.a 
b = v.b 
}. 

Esto no volverá duplicados.

Cuestiones relacionadas