C# 无法创建类型为';System.Int32[]和#x27;。
通过使用以下C# 无法创建类型为';System.Int32[]和#x27;。,c#,entity-framework,linq,C#,Entity Framework,Linq,通过使用以下 PagedData.Products = from p in db.Products where (from m in p.Manufacturers where model.man.Contains(m.ManufacturerID)
PagedData.Products = from p in db.Products
where (from m in p.Manufacturers
where model.man.Contains(m.ManufacturerID)
select m).Any()
where (from s in p.Sizes
where model.size.Contains(s.SizeID)
select s).Any()
where (from c in p.Colors
where model.color.Contains(c.ColorID)
select c).Any()
select p;
我得到这个错误
无法创建“System.Int32[]”类型的空常量值。只有
中支持实体类型、枚举类型或基元类型
这个背景
我知道了错误的原因,但我不知道该如何修复它。
model.man
model.size
和model.color
是整数数组,也可能是空的。由于所有条件都必须为真才能通过任何产品
,您应该首先检查所有数组是否都有任何内容:
if (model.man != null && model.size != null && model.color != null
&& model.man.Any() && model.size.Any() && model.color.Any())
{
PagedData.Products = from p in db.Products ...
现在,如果预先知道查询不会返回任何数据,就不会执行查询。它不会抛出异常,因为您从未使用
null
数组运行查询。我更喜欢使用方法语法和if
s动态构建Where
子句,但是如果您希望将条件嵌入查询中,您需要确保用于包含条件的IEnumerable
s不为null
。这应该发生在查询之外:
var man = model.man ?? Enumerable.Empty<int>();
var size = model.size ?? Enumerable.Empty<int>();
var color = model.color ?? Enumerable.Empty<int>();
PagedData.Products = from p in db.Products
where (from m in p.Manufacturers
where man.Any() && man.Contains(m.ManufacturerID)
select m).Any()
where (from s in p.Sizes
where size.Any() && size.Contains(s.SizeID)
select s).Any()
where (from c in p.Colors
where color.Any() && color.Contains(c.ColorID)
select c).Any()
select p;
还是这个
var query = db.Products.AsQueryable();
if (model.man != null && model.man.Length > 0)
query = query.Where(p => p.Manufacturers.Any(m => model.man.Contains(m.ManufacturerID)));
if (model.size != null && model.size.Length > 0)
query = query.Where(p => p.Sizes.Any(s => model.size.Contains(s.SizeID)));
if (model.color != null && model.color.Length > 0)
query = query.Where(p => p.Colors.Any(c => model.color.Contains(c.ColorID)));
PagedData.Products = query;
您是否尝试过检查空值,如where model.size=null&&model.size.Contains(s.SizeID)
数组可能为null,或者其中的整数可能为null?如果是前者,只需使用一个列表,并将其默认为空即可将int数组更改为可为空的int List(List)?@esiprogrammer是的,但我收到了相同的错误尝试拆分查询以找出例外的确切位置它不是我!:)事实上,并非所有条件都必须为真,我希望where子句之间有类似| |的东西。这是另一个问题,但有一种常见的方法可以做到这一点:除了不需要一些外部库之外,您可以将查询分配给IQueryable变量,并逐步将条件添加到此变量中。@TomTom这只对链接where子句(和
)有用,使用Linqkit,您可以将表达式链接为或
。我从来不喜欢在翻译成SQL的LINQ语句中包含man.Any()
。您是否检查了生成的SQL?必须将本地序列man
转换为表结构,这是通过一系列UNION
-d单行选择来完成的。当阵列“很大”时,这会真正影响性能。如果条件是附加的,当然最后一个代码片段就是正确的选择,尽管您应该添加一个条件,如果所有数组都没有内容,则返回nothing。@GertArnold我也不喜欢它,而更喜欢开头所述的另一种方式。除此之外,我同意如果OP真的希望返回原始查询中的空结果集,那么您的答案会更好,但我的观点是,当null
或empty
时,他可能希望忽略过滤器,并在这种情况下返回完整的结果集。当然这是我的假设,但对我来说听起来很合乎逻辑:)@GertArnold不应该将本地序列man
(这是int
的列表)转换为常量IN(…..)
?是的,它们是,但除此之外,它们还被转换为这个“SQL表”以满足任何。那里有很多冗余。唉。。。对至少他们最近把它变成了更健壮的查询。在以前的版本中,UNION
s被嵌套,导致了“嵌套太深”的SQL错误,数组中只有45-50个元素。
var query = db.Products.AsQueryable();
if (model.man != null && model.man.Length > 0)
query = query.Where(p => p.Manufacturers.Any(m => model.man.Contains(m.ManufacturerID)));
if (model.size != null && model.size.Length > 0)
query = query.Where(p => p.Sizes.Any(s => model.size.Contains(s.SizeID)));
if (model.color != null && model.color.Length > 0)
query = query.Where(p => p.Colors.Any(c => model.color.Contains(c.ColorID)));
PagedData.Products = query;