将T-sql转换为Linq或Entityframework,并且不要对原始查询使用SqlQuery()

时间:2018-07-03 12:39:07

标签: c# entity-framework linq tsql entity-framework-6

我有一个称为Signer的表:

+--------------+----------+---------+--------+--------------+---------+-----------+
|     Name     |    User  |   Order | Signed | CompanyName  | Status  | InvoiceId |
+--------------+----------+---------+--------+--------------+---------+-----------+
|  Anders      |    aa    |       1 |      0 | OvnAnd2      |       0 |     26650 |
|  Peyman      |    pm    |       2 |      1 | OvnAnd2      |       1 |     26650 |
| Siw Ericsson |    se    |       3 |      0 | OvnAnd2      |       0 |     26650 |
|  test        |    test  |       4 |      0 | OvnAnd2      |       0 |     26650 |
|Siw Ericsson  |    se    |       1 |      0 | OvnAnd2      |       0 |     26652 |
|  test        |    test  |       2 |      1 | OvnAnd2      |       0 |     26652 |
|Siw Ericsson  |    se    |       1 |      0 | OvnAnd2      |       0 |     25365 |
+--------------+----------+---------+--------+--------------+---------+-----------+

目标: 如您所见,我有3个不同的InvoiceId。对于每个InvoiceId,我想找到一个最小订单号的行,其中Status列的值为0,而User列必须为se。 (这表示根据其用户名,订单,已签名列显示当前用户已准备好签名的相关发票)

我想出了运行良好的T-SQL:

select * from Signer s1
where s1.User = 'se' and Order = (select min(Order) from Signer s2 where s2.InvoiceId = s1.InvoiceId and Signed = 0)

结果:

+--------------+----------+---------+--------+--------------+---------+-----------+
|     Name     |    User  |   Order | Signed | CompanyName  | Status  | InvoiceId |
+--------------+----------+---------+--------+--------------+---------+-----------+
|Siw Ericsson  |    se    |       1 |      0 | OvnAnd2      |       0 |     26652 |
|Siw Ericsson  |    se    |       1 |      0 | OvnAnd2      |       0 |     25365 |
+--------------+----------+---------+--------+--------------+---------+-----------+

我想将此查询从T-Sql转换为LinqEntityFramework

这是我的解决方案:

        var temp = from x in db.Signers
                    where x.User == Me.UserName &&
                          x.Signed == 0
                          group x by x.InvoiceId
                    into item
                    select new
                    {
                        item.Key,
                        item = item.Min(x => x.Order)
                    };

哪个返回3行,这是错误的,因为Siw应该看到准备好由她签名的相关发票。 (这意味着第一行不​​应在列表中)

+--------------+----------+---------+--------+--------------+---------+-----------+
|     Name     |    User  |   Order | Signed | CompanyName  | Status  | InvoiceId |
+--------------+----------+---------+--------+--------------+---------+-----------+
|  Anders      |    aa    |       1 |      0 | OvnAnd2      |       0 |     26650 |
|Siw Ericsson  |    se    |       1 |      0 | OvnAnd2      |       0 |     26652 |
|Siw Ericsson  |    se    |       1 |      0 | OvnAnd2      |       0 |     25365 |
+--------------+----------+---------+--------+--------------+---------+-----------+

更多信息: -如您在第一张表格中所见,我们有一个特殊的逻辑,即有人可以不按顺序签署发票,而Peyman就是其中之一。 -我不想在SqlQuery()中使用Entityframework方法来执行t-sql查询。

感谢您为我的目标找到解决方案的帮助。 最好的问候

1 个答案:

答案 0 :(得分:1)

我认为这是“让”派上用场的情况之一:

var result = from s in Signers
    let minToSign = Signers.Where(si => 
        si.InvoiceId == s.InvoiceId && si.Signed == 0
    ).Min(si => si.Order)
    where s.User == "se" && s.Order == minToSign
    select s;