LINQ to DataSet - группировать по переменному полю или объединять по условию переменной (с суммой) - PullRequest
1 голос
/ 08 марта 2010

Следующий запрос работает, пока я могу добавить DataRelations. Однако отношение «Table2Table3» больше не может быть четко определено, поэтому я думаю, что мне нужно его удалить. Старое отношение строго включается на 2 строковых поля. Новое отношение существует, если Table2.code = Table3.code и Table2.class = Table3.class ИЛИ Table2.code = Table3.code и Table2.class = "*" и Table3.class - это что угодно.

Как я могу реализовать это условие и по-прежнему суммировать поле Table3.cost?

Могу ли я использовать регулярные выражения?

Я пытался создать анонимное равенство классов (см. Далеко ниже), но таблица 2 не была доступна в правой части предложения equals.

var querytest = from x in ds.Tables[0].AsEnumerable()
                orderby x.Field<int>("Priority")
                select new
                {
                    Name = x.Field<string>("alias"),
                    Amount = x.GetChildRows("Table1Table2")
                           .Sum(product => product.GetChildRows("Table2Table3")
                                    .Sum(tx => tx.Field<decimal>("cost")))
                };

образцы таблиц:

table1: list of aliases and priorities
-----------------
ID alias   priority
1  alias1  1 
2  alias2  2
3  alias3  4
4  alias4  3
table2: children records joined to table1 by ParentID (1-to-many)
-----------------
code  class   ParentID
code1 class1  1
code2 class2  1
code3 class3  2
code4 class4  4
code5 *       3
table3: data, joined on new condition
-----------------
code  class   cost
code1 class1  1.00
code1 class1  10.00
code1 class1  26.00
code2 class2  5.00
code2 class2  0.00
code3 class3  1000.00
code5 class6  25.00
code5 class7  26.00

ожидаемый результат:

alias1 42.00
alias2 1000.00
alias4 0.00
alias3 51.00

Этот запрос не может получить доступ к "кодам" в области действия второго анонимного класса:

var querytest2 = from aliases in ds.Tables[0].AsEnumerable()
                 join codes in ds.Tables[1].AsEnumerable()
                 on aliases.Field<int>("ID") equals codes.Field<int>("ParentID")
                 join data in ds.Tables[2].AsEnumerable()
                 on new {
                     code = codes.Field<string>("code"), classcode = codes.Field<string>("class") } 
                 equals new { 
                     code = data.Field<string>("code"), classcode = (data.Field<string>("class") == "*" ? codes.Field<string>("class") : data.Field<string>("class") }
                 orderby aliases.Field<int>("Priority")
                 select new
                 {
                     name = aliases.Field<string>("alias"),
                     cost = //somehow sum here
                 };

Ответы [ 2 ]

0 голосов
/ 11 марта 2010

Я прибег к двум циклам foreach и четырем отдельным запросам LINQ. Пожалуйста, дайте мне знать, если вы найдете для этого решение с одним оператором LINQ.

0 голосов
/ 09 марта 2010

У меня есть запрос, который почти работает. Вывод немного отключен - «alias3» дублируется одним «lineitem» со стоимостью = 0 (см. Вывод ниже). У класса lineitem есть открытые участники, Заказ, Текст и Стоимость.

var querytest = ((from aliases in Table1.AsEnumerable()
          select new mylineitem
          {
              Order = aliases.Field<int>("Priority")
              Text = aliases.Field<string>("alias"),
              cost = aliases.GetChildRows("Table1Table2")
                  .Where(codes => codes.Field<string>("class") != "*")
                      .Sum(codes => codes.GetChildRows("Table2Table3")
                          .Sum(data => data.Field<decimal>("cost")))
          }).Concat(from aliases in Table1.AsEnumerable()
                    join codes in Table2.AsEnumerable()
                        on aliases.Field<int>("ID") equals codes.Field<int>("ParentID")
                    join data in Table3.AsEnumerable()
                        on codes.Field<string>("code") equals data.Field<string>("code") into temp
                    where codes.Field<string>("class") == "*"
                    select new mylineitem
                    {
                        Order = aliases.Field<int>("Priority"),
                        Text = aliases.Field<string>("alias"),
                        cost = temp.Sum(x => x.Field<decimal>("cost"))
                    })).OrderBy(a => a.Order);

        foreach (var lineitem in querytest)
        {
            Console.WriteLine(lineitem.Text + " " + lineitem.cost);
        }

выход:

alias1 42
alias2 1000
alias4 0
alias3 0 --this line should not be here.
alias3 51
...