2

我使用 Linq 从 4 个级联下拉菜单中返回 ID。

用户可能已经从 1 个或所有菜单中选择了 1 个或多个值。然后从用户的选择中查询代表 ID 的 DataTable 的文本列。

如果用户从第 4 个(也是最低级别)下拉列表中进行选择,那么他们会从上述所有下拉列表中进行选择。

如果用户从菜单 1 中选择“X”,从菜单 2 中选择“Y”,而在其他人中没有任何内容,我希望results1在 [Col_1] 中存在“X”的 10 行中看到,然后会向下查询说results2[Col_2] 中存在“Y”的5 行。

编辑 代码(基本形式)

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取决于results3results3onresults2results2on的结果results1

可能results4 - 2是空的,因此我想知道是否可以将它们合并为最终变量,例如:

var results = results4 ?? results3 ?? results2 ?? results1;

这是抛出错误:

Operator '??' cannot be applied to operands of type 'System.Collections.Generic.IEnumerable<AnonymousType#4>'

有没有人有任何狡猾的想法如何解决这个问题?我尽量不写冗长的代码,处理所有可能的结果。

提前谢谢大家(希望这个问题是有道理的!)

厘米

4

3 回答 3

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)));

这样做的结果是,“return result4,除非它是空的。如果它是空的 return results3。如果results3是空的 return results2,如果results2是空的 return results1。”

如果您认为自己会使用它,可以将其作为扩展方法。它会使它更漂亮,但也会使所有其他IEnumerables 的智能感知变得混乱,因此它可能不值得。

于 2012-05-30T15:06:53.403 回答
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]));

但是,我怀疑,如果你退后一点,你可以做点别的。如果人们经常需要这个扩展,它已经存在(也许。)

于 2012-05-30T15:43:09.110 回答
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 运行它,但应该会遇到一般的想法。

于 2012-05-30T16:13:10.990 回答