C# LINQ到SQL从组中选择字段

C# LINQ到SQL从组中选择字段,c#,linq,linq-to-sql,group-by,C#,Linq,Linq To Sql,Group By,我有一个LINQ to SQL查询,它在某一点上返回两行,我想按ID对它们进行分组并选择特定字段,比如: ID | Field1 | Field2 | Field3 ----------------------------- 1 | 2 | null | 4 1 | 3 | 5 | null ID | Field1 | Field2 | Field3 ----------------------------- 1 | 2 | 5 |

我有一个LINQ to SQL查询,它在某一点上返回两行,我想按ID对它们进行分组并选择特定字段,比如:

ID | Field1 | Field2 | Field3
-----------------------------
1  | 2      | null   | 4
1  | 3      | 5      | null
ID | Field1 | Field2 | Field3
-----------------------------
1  | 2      | 5      | 4
.Select(x => new MyObject {
     Field1 = myGroup.First(x => x.Field4 == 1).Field1,
     Field2 = myGroup.FirstOrDefault(x => x.Field4 == 1) == null ? myGroup.FirstOrDefault(x => x.Field4 == 2).Field2 : myGroup.FirstOrDefault(x => x.Field4 == 1).Field2
});
from g in (from entity in db.Entities
           group entity by entity.Id)
select new
{
    Id = g.Key,
    Field1 = g.Select(e => e.Field1)
              .FirstOrDefault(f => null != f),
    Field2 = g.Select(e => e.Field2)
              .FirstOrDefault(f => null != f),
    Field3 = g.Select(e => e.Field3)
              .FirstOrDefault(f => null != f),
}
此查询的不寻常之处在于,我想从组中选择如下内容:

ID | Field1 | Field2 | Field3
-----------------------------
1  | 2      | null   | 4
1  | 3      | 5      | null
ID | Field1 | Field2 | Field3
-----------------------------
1  | 2      | 5      | 4
.Select(x => new MyObject {
     Field1 = myGroup.First(x => x.Field4 == 1).Field1,
     Field2 = myGroup.FirstOrDefault(x => x.Field4 == 1) == null ? myGroup.FirstOrDefault(x => x.Field4 == 2).Field2 : myGroup.FirstOrDefault(x => x.Field4 == 1).Field2
});
from g in (from entity in db.Entities
           group entity by entity.Id)
select new
{
    Id = g.Key,
    Field1 = g.Select(e => e.Field1)
              .FirstOrDefault(f => null != f),
    Field2 = g.Select(e => e.Field2)
              .FirstOrDefault(f => null != f),
    Field3 = g.Select(e => e.Field3)
              .FirstOrDefault(f => null != f),
}
请注意,该组从两个记录中选择字段。还要注意的是,这不是一个简单的空合并类型操作,因为我需要能够根据其他一些因素选择一个字段1(2或3)

有没有一种聪明的方法可以在选择我想要的特定字段的同时将其投影到新类型中

目前我正在开发IQueryable,因此我需要一个转换为SQL的解决方案,以前查询是这样做的:

ID | Field1 | Field2 | Field3
-----------------------------
1  | 2      | null   | 4
1  | 3      | 5      | null
ID | Field1 | Field2 | Field3
-----------------------------
1  | 2      | 5      | 4
.Select(x => new MyObject {
     Field1 = myGroup.First(x => x.Field4 == 1).Field1,
     Field2 = myGroup.FirstOrDefault(x => x.Field4 == 1) == null ? myGroup.FirstOrDefault(x => x.Field4 == 2).Field2 : myGroup.FirstOrDefault(x => x.Field4 == 1).Field2
});
from g in (from entity in db.Entities
           group entity by entity.Id)
select new
{
    Id = g.Key,
    Field1 = g.Select(e => e.Field1)
              .FirstOrDefault(f => null != f),
    Field2 = g.Select(e => e.Field2)
              .FirstOrDefault(f => null != f),
    Field3 = g.Select(e => e.Field3)
              .FirstOrDefault(f => null != f),
}
这不起作用,因为它不知道如何处理这些操作


我想我们可能会选择一个所有字段都非规范化的组合对象,然后从LINQ选择内存中的对象,但如果可能的话,我宁愿让DB来完成这项工作。

您需要做的是编写C/LINQ表达式来生成SQL CASE语句

一般来说,案例陈述书是:

M = CASE 
WHEN A == P THEN V
WHEN B == Q THEN W
WHEN C == R THEN X
WHEN D == S THEN Y
ELSE Z
END
在这些示例中,所有字母A=p到D=S以及V到Z可以是任何复杂度的任何表达式。例如,你可以说当a.成本>1.5*b.估计然后c.最佳报价

要生成准确的案例陈述,您需要以下LINQ/C:

M =
(
  A == P? V :
  B == Q? W :
  C == R? X :
  D == S? Y :
  Z
)
因此,为了直接解决未说明的问题,可以使用三元运算符为每个字段的值编写任意条件,这些条件将转换为LINQ CASE语句

另请参见以下内容并将其归功于:


如果我理解你的要求,应该是这样的:

ID | Field1 | Field2 | Field3
-----------------------------
1  | 2      | null   | 4
1  | 3      | 5      | null
ID | Field1 | Field2 | Field3
-----------------------------
1  | 2      | 5      | 4
.Select(x => new MyObject {
     Field1 = myGroup.First(x => x.Field4 == 1).Field1,
     Field2 = myGroup.FirstOrDefault(x => x.Field4 == 1) == null ? myGroup.FirstOrDefault(x => x.Field4 == 2).Field2 : myGroup.FirstOrDefault(x => x.Field4 == 1).Field2
});
from g in (from entity in db.Entities
           group entity by entity.Id)
select new
{
    Id = g.Key,
    Field1 = g.Select(e => e.Field1)
              .FirstOrDefault(f => null != f),
    Field2 = g.Select(e => e.Field2)
              .FirstOrDefault(f => null != f),
    Field3 = g.Select(e => e.Field3)
              .FirstOrDefault(f => null != f),
}
请注意,如果–对于任何给定的Fieldx–该组中没有该字段的非空值,则结果Fieldx值将为空