我使用Linq从4个级联下拉菜单中返回ID。
用户可能已从1个或所有菜单中选择了1个或多个值。从用户选择中,我然后查询DataTable的文本列以获取代表ID。
如果用户从第4(和最低级别)下拉菜单中进行选择,那么他们将从上述所有选项中进行选择。
如果用户从菜单1中选择“X”,从菜单2中选择“Y”,而在其他人中没有任何内容我希望看到results1
表示[Col_1]中存在“X”的10行,然后将在results2
中查询5行,其中“Col”中存在“Y”。
修改 守则(基本形式)
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>'
这引发了错误:
{{1}}
有没有人有任何狡猾的想法如何解决这个问题?我尽量不写很长的啰嗦代码,处理每一个可能的结果。
提前谢谢大家(希望这个问题有道理!)
CM
答案 0 :(得分:5)
因此,根据您使用的查询,结果都不会是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
,如果{{1}是空的返回results2
。“
如果您认为自己足够使用它,可以将其作为扩展方法。它会使它更漂亮,但也会使所有其他results1
的智能感知混乱,所以它可能不值得。
答案 1 :(得分:0)
如果您不想编写冗长的代码,可以
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]));
但是,我怀疑,如果你退后一步,你可以做点别的事。如果人们经常需要这种扩展,那么它可能已经存在(也许。)
答案 2 :(得分:0)
我会重写查询以解决问题,而不是在事后处理它。
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,但总的想法应该会遇到。