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.
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.
C'est parce que vous avez un contrôle nul dans la clause where.
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; }
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() )
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