无法比较类型的元素' System.Collections.Generic.ICollection`1仅支持基本类型,枚举类型和实体类型

时间:2014-05-29 15:35:02

标签: c# linq entity-framework

我写了这段代码

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();

但是在ToList行,我收到了异常

  

无法比较类型的元素   &#39; System.Collections.Generic.ICollection`1 [[Project1,Version = 1.0.0.0,   Culture = neutral,PublicKeyToken = null]]&#39;。只有原始类型,   支持枚举类型和实体类型。

6 个答案:

答案 0 :(得分:51)

您无法直接将相关表格与null进行比较。相反,请与您的外键成员进行比较(假设使用名为PrimaryTable的成员RelatedTable引用RelatedTableId

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

您甚至可以完全删除空检查。由于此查询是针对数据库运行的,因此您将无法获得NullReferenceException并且它可能会起作用。你必须仔细检查一下。

答案 1 :(得分:11)

这是因为你在where子句中进行了空检查。

答案 2 :(得分:5)

如果导航集合与null比较,则会发生错误。应检查是否存在任何记录。在特定示例中,无论如何都使用Any,因此将collection collection设置为null是多余的

<强>不正确

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

<强>正确

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

答案 3 :(得分:4)

收集字段可以为null,在这种情况下,您将获得异常NullReferenceException

使用时RelatedTables.Any()

如果您在问题中添加RelatedTables != null,那么您可以

  

无法比较类型的元素   &#39; System.Collections.Generic.ICollection`1 [[Project1,Version = 1.0.0.0,   Culture = neutral,PublicKeyToken = null]]&#39;。只有原始类型,   支持枚举类型和实体类型。

如果您收到NullReferenceException异常,则延迟加载不会被关闭,并且您对该字段的延迟加载很好,然后阻止带有virtual关键字的异常标记字段以允许延迟加载字段

virtual ICollection<Table> RelatedTables{ get; set; }

答案 4 :(得分:0)

我没有配置外键字段,因为在我的情况下,MainTableRelatedTable之间的关系是1到1。但是,如果您没有外键,则是一对多的关系键,但是您在MainTable模型中拥有RelatedModel模型的导航属性,因此以下解决方案也适用。     

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对多

  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

答案 5 :(得分:-1)

它对我有用,我只是删除空检查;

正确的: 结果=

&#13;
&#13;
db.EmpTable.FirstOrDefault().ProjectsAssign.Name,
&#13;
&#13;
&#13;

InCorrect: 结果=

&#13;
&#13;
db.EmpTable!=null && db.EmpTable.FirstOrDefault().ProjectsAssign!=null ? 
      db.EmpTable.FirstOrDefault().ProjectsAssign.Name : null,
&#13;
&#13;
&#13;