简体   繁体   English

用于根据另一个表中的值对表进行分组的 LINQ 查询

[英]LINQ query for grouping a table based on the values from another table

I am trying write C# LINQ to join a table based on the values from a different table我正在尝试编写 C# LINQ 以根据不同表中的值加入一个表

For example, I have two tables Table1 and Table2 as below例如,我有两个表 Table1 和 Table2 如下

Table1

Id Name Address StatusId SubStatusId Dubs
1  ABC  XYZ     1         39         10
2  PQR  XYZ     1         39         0
3  ME   WWW     2         39         5
4  YOU  XYZ     1         22         0
5  HE   XYZ     2         22         5 
6  SHE  WWW     2         41         0
7  XAZ  XYZ     1         39         10

Table2
Id StatusId SubStatusId Status   SubStatus  Type
1  1         39         Dispense  Ready     1
2  1         39         Fill      Ready     2
3  2         22         Ship      Active    0
4  2         41         Del       Pending   0
5  1         22         Verify    Pending   0   
6  2         39         Benefit   None      0

Now, I am trying to join both tables with StatusId and SubstatusId Columns as follows现在,我正在尝试将两个表与StatusId and SubstatusId列连接起来,如下所示

 from p in context.Table1
                     join label in context.Table2 on new
                     {
                         p.StatusId,
                         p.SubStatusId,                      
                         I = p.Dubs== 0,
                         J = p.Dubs> 0
                     } equals
                         new
                         {
                             label.StatusId,
                             label.SubStatusId,                          
                             I = label.type== 1
                             J = label.type== 2
                         } into gj
                     from label in gj.DefaultIfEmpty()

The above code join two tables by four values properties but I would like to exclude I and J when type of the row in Table2 is zero no matters what value is in Dubs上面的代码通过四个值属性连接两个表,但是当Table2中的行类型为零时,我想排除 I 和 J,无论Dubs值是什么

Result looks like below结果如下所示

Status   SubStatus
Fill      Ready (1,39 Since Dubs>0 for which means should return row with type 2)
Dispense  Ready (1,39 Since Dubs=0 for which means should return row with type 1)
Benefit   None (2, 39 Since type=0, this should ignore Dubs)
Verify    Pending (same as above)
Ship      Active
Del       Pending
Fill      Ready  (1,39 Since Dubs>0 for which means should return row with type 2)

I would keep the more complex predicates out of the join:我会将更复杂的谓词排除在连接之外:

from p in context.Table1
join label in context.Table2 on new
{
    p.StatusId,
    p.SubStatusId,                      
} equals new
{
    label.StatusId,
    label.SubStatusId,                          
} into gj
from label in gj.DefaultIfEmpty()
where label.Type == 0
   || label.Type == (p.Dubs == 0 ? 1 : 2)
select ...

The join syntax seems easier to control inside of a Where.连接语法在 Where 中似乎更容易控制。 The where doesn't match yours, but you should be able to build the complex clause based upon this more easily. where 与您的不匹配,但您应该能够更轻松地基于此构建复杂的子句。

var aresult = from a in ta.AsEnumerable()
              from b in tb.AsEnumerable()
             .Where(b => a.Field<string>("StatusId") == b.Field<string>("StatusId")
                      && a.Field<string>("SubStatusId") == b.Field<string>("SubStatusId"))

              select new object[] { a.Field<string>("Name")
                                   ,b.Field<string>("Status")
                                  ,b.Field<string>("SubStatus")
              };

Code to generate tables given ...生成给定表的代码...

    DataTable ta = new DataTable();
    ta.Columns.Add("Id");
    ta.Columns.Add("Name");
    ta.Columns.Add("Address");
    ta.Columns.Add("StatusId");
    ta.Columns.Add("SubStatusId");
    ta.Columns.Add("Dubs");

    DataTable tb = new DataTable();
    tb.Columns.Add("Id");
    tb.Columns.Add("StatusId");
    tb.Columns.Add("SubStatusId");
    tb.Columns.Add("Status");
    tb.Columns.Add("SubStatus");
    tb.Columns.Add("Type");

    string[] tas =
    {
         "1,ABC,XYZ,1,39,10"
        ,"2,PQR,XYZ,1,39,20"
        ,"3,ME,WWW,2,39,0"
        ,"4,YOU,XYZ,1,22,2"
        ,"5,HE,XYZ,2,22,5"
        ,"6,SHE,WWW,2,41,0"
    };
    string[] tbs =
    {
        "1,1,39,Dispense,Ready,1"
       ,"2,2,39,Fill,Ready,2"
       ,"3,2,22,Ship,Active,0"
       ,"4,2,41,Del,Pending,0"
       ,"5,1,22,Verify,Pending,0"
    };
    foreach (string t in tas)
    {
        string[] x = t.Split(',');
        DataRow row = ta.NewRow();
        for (int i = 0; i < x.Length; i++) row[i] = x[i];
        ta.Rows.Add(row);
    }
    foreach (string t in tbs)
    {
        string[] x = t.Split(',');
        DataRow row = tb.NewRow();
        for (int i = 0; i < x.Length; i++) row[i] = x[i];
        tb.Rows.Add(row);
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM