如何将多个linq查询组合到一个结果集中?

我有一个多选复选框。 根据检查的是哪一个,我想将结果合并到一个查询中。 有点像:

if (Checkbox1.Checked) { var query1 = from t in table1 ... } if (Checkbox2.Checked) { var query2 = from t in table2 ... } DataGridView1.DataSource = query1.Union(query2); // obviously doesnt // work since query1 and query2 are not defined in this scope. 

知道如何有选择地组合这些吗?

假设查询类型相同,您可以在条件语句之外定义查询。

首先,一个辅助方法,它创建一个与参数相同类型的空可枚举:

 static IEnumerable CreateEmptyEnumerable(IEnumerable templateQuery) { return Enumerable.Empty(); } 

然后,新代码:

 var query1 = from t in table1 ... var query2 = from t in table2 ... var finalQuery = CreateEmptyEnumerable(query1); if (Checkbox1.Checked) { finalQuery = query1; } if (Checkbox2.Checked) { finalQuery = finalQuery.Union(query2); } DataGridView1.DataSource = finalQuery.ToList(); // to avoid re-enumeration 

这样做很好,因为查询在枚举之前不会被实际执行,就像调用ToList()

如果您不使用var但是已知类型,则可以通过初始化query1和query2

如果未选中复选框,则为Enumerable.Empty

我只是在控制台应用程序中试过这个,因为我很好奇,它只是起作用….

 class Program { private class Data1 { public int Code1 { get; set; } public string Value1 { get; set; } } private class Data2 { public int Code2 { get; set; } public string Value2 { get; set; } } static void Main(string[] args) { var data1 = new[] { new Data1 { Code1 = 1, Value1 = "one" }, new Data1 { Code1 = 2, Value1 = "two" }, new Data1 { Code1 = 3, Value1 = "three" } }; var data2 = new[] { new Data2 { Code2 = 101, Value2 = "aaa" }, new Data2 { Code2 = 102, Value2 = "bbb" }, new Data2 { Code2 = 103, Value2 = "ccc" } }; var query1 = from d1 in data1 select new { code = d1.Code1, text = d1.Value1 }; var query2 = from d2 in data2 select new { code = d2.Code2, text = d2.Value2 }; var datasource = query1.Union(query2); foreach (var d in datasource) { Console.WriteLine(d); } } } 

但是,如果我将匿名类型中的字段名更改为不同,则会出现编译器错误,因此看起来关键是要在匿名类型中使用相同的名称。 或者只是将结果定义为已定义的类型:)

使用Rx你可以这样做:

 public partial class _Default : System.Web.UI.Page { IEnumerable table1; IEnumerable table2; protected void Page_Load(object sender, EventArgs e) { table1 = Enumerable.Range(0, 10); table2 = Enumerable.Range(10, 10); } protected void Button1_Click(object sender, EventArgs e) { var query = Observable.If(() => CheckBox1.Checked, (from t in table1 select t).ToObservable(), Observable.Empty()) .Concat( Observable.If(() => CheckBox2.Checked, (from t in table2 select t).ToObservable(), Observable.Empty()) ); query.Subscribe(i => Response.Write(i)); } }