合并可能为空的 LINQ 查询结果
本文关键字:LINQ 查询 结果 合并 | 更新日期: 2023-09-27 18:35:41
我使用 Linq 从 4 个级联下拉菜单返回 ID。
用户可能已从 1 个或所有菜单中选择了 1 个或多个值。 然后,从用户选择中,我查询数据表的文本列以获取代表性 ID。
如果用户从第 4 个(也是最低级别)下拉列表中选择,那么他们将从上述所有下拉列表中选择。
如果用户从菜单 1 中选择"X",从菜单 2 中选择"Y",而在其他菜单中没有任何内容,我希望看到results1
,比如 10 行,其中"X"存在于 [Col_1] 中,然后向下查询到results2
5 行,其中"Y"存在于 [Col_2]。
编辑守则(基本形式)
var results1 =
from a in dt.AsEnumerable()
where stringArray1.Contains([Col1])
select a;
var results2 =
from a in results1
where stringArray2.Contains([Col2])
select a;
var results3 =
from a in results2
where stringArray3.Contains([Col3])
select a;
var results4 =
from a in results3
where stringArray4.Contains([Col4])
select a;
var results = results4 ?? results3 ?? results2 ?? results1;
results4
取决于results3
的结果,results3
取决于results2
,results2
取决于results1
。
可能是results4 - 2
是空的,因此我想知道我是否可以将它们合并成一个最终变量,例如:
var results = results4 ?? results3 ?? results2 ?? results1;
这是抛出错误:
Operator '??' cannot be applied to operands of type 'System.Collections.Generic.IEnumerable<AnonymousType#4>'
有没有人有任何狡猾的想法如何解决这个问题? 我尽量不写很长的代码,处理每一个可能的结果。
提前谢谢大家(希望这个问题有意义!
厘米
因此,根据您使用的查询,任何结果都不会null
。 其中一些可能是空的,但它们不会null
。 这意味着??
运算符永远不会做任何有用的事情。
您希望它如何表现? 你想说,"如果这个结果是空的,使用另一个结果? 为此,请使用我在下面编写的方法。
public static IEnumerable<T> Coalesce<T>(IEnumerable<T> first, IEnumerable<T> second)
{
if(first == null || !first.Any())
{
return second;
}
else
{
return first;
}
}
然后,这可以用作:
Coalesce(results4, Coalesce(results3, Coalesce(results2, results1)));
这样做的结果是,"返回result4
,除非它是空的。 如果是空返回results3
. 如果results3
为空,则返回results2
,如果results2
为空,则返回results1
。
如果您认为使用它足够多,可以将其设置为扩展方法。 它会让它更漂亮,但也会使所有其他IEnumerable
的智能感觉变得混乱,所以它可能不值得。
如果你不想写冗长的代码,你可以这样做
public static IEnumerable<T> SomeOrAll<T>(
this IEnumerable<T> source,
Predicate<T> where)
{
var results = source.Where(where)
return results.Any() ? results : source;
}
var results = dt.AsEnumerable()
.SomeOrAll(a => a.stringArray4.Contains([Col4]))
.SomeOrAll(a => a.stringArray3.Contains([Col3]))
.SomeOrAll(a => a.stringArray2.Contains([Col2]))
.SomeOrAll(a => a.stringArray1.Contains([Col1]));
但是,我怀疑,如果你退后一步,你可以做别的事情。如果人们经常需要这个扩展,它已经存在(也许)。
我会重写查询来解决问题,而不是在事后处理它。
public List<string> FilterResults(string first, string second, string third, string fourth)
{
var query = from a in dt.AsEnumerable()
let firsts = first != null ? a.Where( x => x.stringArray1.Contains( first ) ) : null,
let seconds = second != null ? firsts.Where( x => x.stringArray2.Contains( second ) ) : null,
let thirds = third != null ? seconds.Where( x => x.stringArray3.Contains( third ) ) : null,
let fourths = fourth != null ? thirds.Where( x => x.stringArray4.Contains( fourth ) ) : null
select fourths ?? thirds ?? seconds ?? firsts;
return query.ToList();
}
我没有运行这个虽然 VS,但总体想法应该会遇到。