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

时间:2017-10-24 19:20:28

标签: c# sql-server linq

我正在尝试编写C#LINQ来基于来自不同表的值

来连接表

例如,我有两个表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

现在,我正在尝试使用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()

上面的代码通过四个值属性连接两个表,但我希望在Table2中的行的类型为零时排除I和J无关Dubs

中的值是什么

结果如下所示

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)

2 个答案:

答案 0 :(得分:1)

我会将更复杂的谓词保留在连接之外:

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

答案 1 :(得分:0)

连接语法似乎更容易控制在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")
              };

生成给定表格的代码......

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