2010-11-09 11 views
10

Estoy intentando crear una colección jerárquica usando Entity Framework - vea la consulta a continuación - cada miembro de una compañía dada tiene un miembro padre - pero cuando trato de ejecutar esto obtengo la siguiente excepción:Hierarchical Entity Framework Query Exception

System.NotSupportedException: El tipo 'miembro' aparece en dos estructuralmente inicializaciones incompatibles dentro de una sola LINQ a Entidades consulta. Un tipo se puede inicializar en dos lugares en la misma consulta, pero solo si las mismas propiedades se establecen en ambos lugares y esas propiedades se establecen en el mismo orden .

Si elimino la asignación de ParentMember, funciona: ¿alguna idea sobre lo que está sucediendo?

 return from c in _Entities.Company 
       where c.Deleted == false 
       select new Member() 
       { 
        Name = c.Name, 
        ParentMember = new Member() 
        { 
         Name = c.ParentMember.Name 
        } 
       }; 

Respuesta

12

No he probado esto, pero el mensaje de error que da una pista: no se está configurando las mismas propiedades en el mismo orden en ambos lugares.

¿Qué ocurre si intenta establecer una propiedad de ID en el miembro externo()?

+0

He acaba de actualizar el código en la pregunta para reflejar el código real - Tengo exactamente las mismas propiedades que se establecen en el mismo orden con la excepción de establecer la propiedad ParentMember del ParentMember, si eso tiene sentido. –

+1

En realidad, todavía no está configurando todos los mismos params: el exterior tiene Nombre y ParentMember, mientras que solo está configurando el Nombre para el interior. Intente asignarle un valor nulo a la propiedad. – chris

1

Terminará con una recursión de registros de miembros cuando intente recuperar los mismos campos en cada uno. No puede simplemente hacer que el último registro principal sea igual a nulo.

Recuperé todo lo que pude y luego creé el registro con más consultas. Tenga en cuenta que la entidad de su compañía requerirá un campo ParentId o similar.

var members = 
    return from c in _Entities.Company 
    select new Member() 
    { 
    Name = c.Name, 
    ParentId = c.ParentId 
    }; 

Ahora itere y agregue los registros principales.

foreach (var member in members) 
{ 
    member.ParentMember = new Member 
    { 
     Name = _Entities.Company.First(c => c.Id == member.ParentId).Name 
    }; 
} 
2

Trate

return (from c in _Entities.Company 
       where c.Deleted == false 
       select new 
       { 
        c.Name, 
        ParentMember = new 
        { 
         c.ParentMember.Name 
        } 
       }) 
.AsEnumerable() 
.Select(c=> new Member 
       { 
        Name = c.Name, 
        ParentMember = new Member 
        { 
         Name = c.ParentMember.Name 
        } 
       }); 
+2

+1 Esta situación de catch-22 me mordió, y esta fue la solución que se me ocurrió de forma independiente. Menos elegante de lo que esperaba, y un poco derrochador, ya que tenemos que duplicar la instanciación de objetos, pero no obstante es efectivo. –