【问题标题】:Cannot compare elements of type 'System.Collections.Generic.ICollection`1 Only primitive types, enumeration types and entity types are supported无法比较类型为“System.Collections.Generic.ICollection”1 的元素仅支持原始类型、枚举类型和实体类型
【发布时间】:2014-05-29 15:35:02
【问题描述】:

我已经写了这段代码

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 行我遇到了异常

无法比较类型的元素 'System.Collections.Generic.ICollection`1[[Project1,版本=1.0.0.0, 文化=中性,PublicKeyToken=null]]'。只有原始类型, 支持枚举类型和实体类型。

【问题讨论】:

    标签: c# linq entity-framework


    【解决方案1】:

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

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

    您甚至可以完全删除空检查。由于此查询是针对数据库运行的,因此您不会得到NullReferenceException,它可能会起作用。不过,您必须仔细检查。

    【讨论】:

    • 我删除了空检查,代码抛出了一个未设置为引用异常的对象。
    • 奇怪。作为 IQueryable,如果您使用实体,则不应发生这种情况。无论如何,如果你把它放在里面,它会起作用吗?
    • 你是对的。我的代码中还有其他错误。
    • 没看懂,RelatedTable是一个列表,怎么会有RelatedTableId?我的没有这个。
    • 我正在使用 sRelatedTable.Where(p => p.Name == param1.ToLower()).Any() 我为您的解决方案更改了它,现在正在使用谢谢!
    【解决方案2】:

    这是因为您在 where 子句中有一个空检查。

    【讨论】:

    • 好奇怪又简单
    • 这根本不对。在 where 子句中一直使用空检查。这是对代表问题的包含表的 ICollection 的空检查...
    【解决方案3】:

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

    不正确

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

    正确

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

    【讨论】:

    • 仍然不完美,尤其是在对象 (mainTable) 对嵌套子级 (relatedTable) 具有空引用的情况下,此解决方案最终会出现异常,因为 Any() 不与空值进行比较。从业务逻辑的角度来看,@Nathan A 的解决方案看起来更正确。
    【解决方案4】:

    Collection 字段可以为 null 在这种情况下你会得到异常 NullReferenceException

    当使用RelatedTables.Any()

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

    无法比较类型的元素 'System.Collections.Generic.ICollection`1[[Project1,版本=1.0.0.0, 文化=中性,PublicKeyToken=null]]'。只有原始类型, 支持枚举类型和实体类型。

    如果您收到NullReferenceException 异常,则延迟加载不会关闭,并且您可以很好地对该字段进行延迟加载,然后使用virtual 关键字防止异常标记字段以允许对该字段进行延迟加载

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

    【讨论】:

      【解决方案5】:

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

      1对1

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

      一对多

        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
      

      【讨论】:

        【解决方案6】:

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

        正确: 结果=

        db.EmpTable.FirstOrDefault().ProjectsAssign.Name,

        不正确: 结果=

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-02-20
          • 1970-01-01
          • 2019-05-09
          • 2014-11-16
          • 1970-01-01
          相关资源
          最近更新 更多