linq 无法比较类型为“System.Collections.Generic.ICollection”1的元素,仅支持基元类型、枚举类型和实体类型

ndasle7k  于 2022-12-20  发布在  其他
关注(0)|答案(7)|浏览(259)

我写了这段代码

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”1Project1,版本=1.0.0.0,区域性=neutral,PublicKeyToken=null“的元素。仅支持基元类型、枚举类型与实体类型。

qgzx9mmu

qgzx9mmu1#

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

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

你甚至可以完全取消空值检查,因为这个查询是针对数据库运行的,你不会得到一个NullReferenceException,它可能会工作,但是你必须再次检查。

nzk0hqpo

nzk0hqpo2#

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

c9qzyr3d

c9qzyr3d3#

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

不正确

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

正确

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

hrirmatl4#

在这种情况下,收集字段可以为空,您将获得异常NullReferenceException
当使用RelatedTables.Any()
如果在问题中加上RelatedTables != null,则可以得到
无法比较类型为"System. Collections. Generic. ICollection" 1 Project1,版本= 1.0.0.0,区域性= neutral,PublicKeyToken = null"的元素。仅支持基元类型、枚举类型与实体类型。
如果出现NullReferenceException异常,延迟加载未关闭,并且您擅长于延迟加载字段,则使用virtual关键字阻止异常标记字段以允许延迟加载字段

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

y3bcpkx15#

我没有配置外键字段,因为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;

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
9fkzdhlc

9fkzdhlc6#

我也有同样的情况,然后通过比较null和FirstOrDefault()通过了,在你的情况下,我是按照下面的方法申请的

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

kxxlusnw7#

它对我有用,我只是去掉了空校验;
正确:结果=

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

不正确:结果=

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

相关问题