web-dev-qa-db-fra.com

Impossible de comparer des éléments de type 'System.Collections.Generic.ICollection`1 Seuls les types primitifs, les types d'énumération et les types d'entité sont pris en charge.

J'ai écrit ce code

IQueryable<Site> sites = context.MainTable.Include("RelatedTable");

if (!string.IsNullOrEmpty(param1)) {
    sites = sites.Where(s => s.RelatedTable != null && s.RelatedTable.Any(p => p.Name == param1.ToLower() && p.PolicyType == "primary"));
}

foreach (string secondaryPolicy in secondaryPolicies)
{
    sites = sites.Where(s => s.RelatedTable != null && s.RelatedTable.Any(p => p.Name == secondaryPolicy.ToLower() && p.PolicyType == "secondary"));
}

return sites.ToList();

Cependant, à la ligne ToList, je reçois l'exception

Impossible de comparer les éléments de type 'System.Collections.Generic.ICollection`1 [[Projet1, version = 1.0.0.0, Culture = neutre, PublicKeyToken = null]] '. Seuls les types primitifs, les types d'énumération et les types d'entité sont pris en charge.

33
Knows Not Much

Vous ne pouvez pas comparer directement une table liée à null. Au lieu de cela, comparez avec votre membre de clé étrangère (en supposant que PrimaryTable référence RelatedTable en utilisant un membre appelé RelatedTableId.

sites.Where(s => s.RelatedTableId != null && s.RelatedTable.Any(
    p => p.Name == param1.ToLower() && p.PolicyType == "primary"));

Vous pourrez peut-être même vous en sortir en supprimant complètement le chèque nul. Étant donné que cette requête est exécutée sur la base de données, vous ne recevrez pas NullReferenceException et cela peut fonctionner. Vous devrez cependant vérifier cela.

50
Nathan A

C'est parce que vous avez un contrôle nul dans la clause where. 

11
Matt

Le champ de collection peut être nul dans ce cas, vous obtenez une exception NullReferenceException

quand utiliser RelatedTables.Any()

Si vous ajoutez RelatedTables != null comme dans une question, vous pouvez obtenir

Impossible de comparer les éléments de type 'System.Collections.Generic.ICollection`1 [[Projet1, version = 1.0.0.0, Culture = neutre, PublicKeyToken = null]] '. Seuls les types primitifs, les types d'énumération et les types d'entité sont pris en charge.

Si vous obtenez l'exception NullReferenceException, le chargement différé n'est pas désactivé et le chargement différé du champ vous convient, puis d'empêcher le champ de marque d'exception avec le mot clé virtual afin de permettre le chargement différé du champ

virtual ICollection<Table> RelatedTables{ get; set; }
4
Daniil Grankin

L'erreur peut se produire si la collection de navigation est comparée à null. Il convient de vérifier si tout enregistrement existe. Dans l'exemple particulier, Any est utilisé de toute façon, donc vérifier que la collection est nulle est redondante

Incorrect

dbContext.MainTable.Where(c => c.RelatedTable==null )

Correct

dbContext.MainTable.Where(c => !c.RelatedTable.Any() )
4
Michael Freidgeim

Je n'ai pas de champ de clé étrangère configuré car la relation entre MainTable et RelatedTable est dans mon cas de 1 à 1. Toutefois, pour une relation de 1 à plusieurs si vous n'avez pas de clé étrangère mais que vous avez une propriété de navigation dans le modèle MainTable dans le modèle RelatedModel, la solution suivante fonctionne également . 

1 à 1

  var result = from s in context.Sites
               join r in context.RelatedTable on s.Id equals r.Id
               select s; 

  return result;

1 à plusieurs

  var result = from s in context.Sites
               join r in context.RelatedTable on s.Id equals r.Site.Id
               into rs
               where rs.RelatedTable.Any(p => p.Name == param1.ToLower() && p.PolicyType == "primary")
               select s
0
Dalsier