将SQL转换为Lambda/Linq

本文关键字:Linq Lambda SQL 转换 | 更新日期: 2023-09-27 18:15:16

我一直在尝试将相当基本的SQL代码转换为lambda或Linq,但我无处可去。下面是SQL查询:

SELECT * FROM Form a 
INNER JOIN FormItem b ON a.FormId = b.FormId
INNER JOIN FormFee c ON a.FormId = c.FormId 
INNER JOIN FeeType d ON c.FeeTypeId = d.FeeTypeId
WHERE b.StatusId = 7

我试过了,但是它不是我想要的。

public Form GetFormWithNoTracking(int id)
{
    return ObjectSet
       .Where(x => x.FormId == id && 
                  (x.FormItem.Any(di => di.StatusId == (short)Status.Paid)))
       .AsNoTracking()
       .FirstOrDefault();
}

我试图只返回FormItemStatusIdPaid的行。但是,上面的返回全部。我知道.Any()将检查是否有任何匹配,如果有返回所有,所以在这种情况下,我的数据,对于这个表单,确实有StatusIdPaid的项目和一些StatusId未支付的项目,因此它将它们全部带回来。

将SQL转换为Lambda/Linq

var query = (from a in ObjectSet.FormA
             join b in ObjectSet.FormB on a.field equals b.field
             where b.StatusId = 7
             select new { a, b})

您可以使用相同的逻辑连接rest。

这应该是你所要求的:

  1. FormId = id获取Form
  2. 返回所有具有StatusId = Paid
  3. FormItems
public IEnumerable<FormItem> GetFormWithNoTracking(int id)
{
    return ObjectSet
        .SingleOrDefault(x => x.FormId == id)
        .Select(f => f.FormItem
            .Where(di => di.StatusId == (short)Status.Paid))
        .AsNoTracking();
}

如果你也需要Form本身,你可能想要创建一个自定义类型(编辑:见@Burk的回答)或返回一个Tuple<Form,IEnumerable<FormItem>>,一个IEnumerable<Tuple<Form,FormItem>>或任何最适合你的需求。

或者您可以删除表单中所有未付费项。

public Form GetFormWithNoTracking(int id)
{
    var form = ObjectSet
        .SingleOrDefault(x => x.FormId == id)
        .AsNoTracking();
    var nonPaid = form.Select(f => f.FormItem
            .Where(di => di.StatusId != (short)Status.Paid)).ToList();
    foreach(FormItem item in nonPaid)
        form.FormItem.Remove(item);
    return form;
}