2010-11-09 10 views
10

Je tente de créer une collection hiérarchique à l'aide d'Entity Framework - voir la requête ci-dessous - chaque membre d'une société a un membre parent - mais lorsque j'essaie de l'exécuter, j'obtiens l'exception suivante:Exception de requête de structure d'entité hiérarchique

System.NotSupportedException: Le type « membre » apparaît dans deux structurellement initialisations incompatibles au sein d'une seule LINQ à la requête des entités. Un type peut être initialisé à deux endroits dans la même requête, mais seulement si les mêmes propriétés sont définies aux deux endroits et ces propriétés sont définies dans la même commande .

Si je supprime l'objet ParentMember, cela fonctionne - des idées sur ce qui se passe?

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

Répondre

12

Je n'ai pas essayé cela, mais le message d'erreur vous donne un indice: vous ne définissez pas les mêmes propriétés dans le même ordre dans les deux endroits. Que se passe-t-il si vous essayez de définir une propriété ID sur le membre externe()?

+0

J'ai juste mis à jour le code dans la question afin de refléter le code réel - j'ai exactement les mêmes propriétés définies dans le être même ordre à l'exception de définir la propriété ParentMember de ParentMember, si cela a du sens. –

+1

En fait, vous ne définissez pas toujours les mêmes paramètres: l'externe a Name et ParentMember, alors que vous ne définissez que le nom pour l'intérieur. Essayez d'attribuer une valeur nulle à la propriété. – chris

1

Vous obtiendrez une récursivité des enregistrements de membre lorsque vous essaierez de récupérer les mêmes champs dans chacun d'entre eux. Vous ne pouvez pas rendre le dernier enregistrement parent égal à null.

Je voudrais récupérer ce que je pouvais et ensuite construire l'enregistrement avec d'autres requêtes. Notez que votre entité de société nécessitera un champ ParentId ou similaire.

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

Maintenant itérer et ajouter dans les enregistrements parent.

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

Essayez

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 Cette situation de catch-22 m'a un peu mordue, et c'est la solution que j'ai trouvée indépendamment. Moins élégant que j'espérais, et un peu inutile, puisque nous devons doubler l'instanciation de l'objet, mais néanmoins efficace. –

Questions connexes