2010-07-01 3 views
3

У меня есть флажок для нескольких элементов. В зависимости от того, какой из них отмечен, я хочу объединить результаты в один запрос. Пример:Как объединить несколько запросов 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. 

Любая идея, как объединить эти выборочно?

ответ

7

Предполагая, что запросы одного типа, вы можете определить запросы вне условных операторов.

Во-первых, вспомогательный метод, который создает пустой перечислимых того же типа в качестве параметра:

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

Затем новый код:

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().

+0

Вы не можете присвоить NULL для неявно типизированных локальных переменных. – esac

+0

Ben M - Я помню это сейчас, но я все еще не могу сделать «var finalQuery = null;» – esac

+0

Я основываю свой ответ на том, что ваш запрос перечисляет анонимный тип. Если нет, вы можете просто заменить 'var' на' IEnumerable '. –

0

Если вы не использовали бы вар, но известный тип, то вы можете инициализировать Query1 и Query2 через

Enumerable.Empty<T> в случае флажок не проверяется.

0

Я просто попытался это в консольном приложении, так как мне было интересно, и он просто работал ....

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

Однако, если я изменить имена полей в анонимных типов, чтобы быть разными, я получаю ошибка компилятора, поэтому похоже, что ключ должен иметь имена одинаковые в ваших анонимных типах. Или просто результат в определенном типе :)

+0

Хмм, я пропустил, в чем проблема? –

+0

Да, я уже знаю, что Союз работает. Проблема в том, что мои анонимные типы были объявлены в операторах if, что делает так, что вы не можете делать Union за пределами операторов if. – esac

+0

, если анонимные типы одинаковы, почему бы просто не сделать частный класс и использовать его? –

0

Rx Использование вы можете сделать что-то вроде этого:

public partial class _Default : System.Web.UI.Page 
{ 
    IEnumerable<int> table1; 
    IEnumerable<int> 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<int>()) 
      .Concat(
       Observable.If(() => CheckBox2.Checked, 
       (from t in table2 select t).ToObservable(), Observable.Empty<int>()) 
      ); 

     query.Subscribe(i => Response.Write(i)); 
    } 
} 
Смежные вопросы