如何将我的SQL语句转换为LINQ

时间:2017-10-06 17:41:17

标签: sql-server asp.net-mvc linq

我是LINQ的新手,并且对一些简单的LINQ了解甚少。但是现在,我拥有的东西比我能做的更复杂。我已经创建了SQL语句,尝试了它并且它可以工作。但我无法将其转换为LINQ。

编辑:我尝试对linq进行编码并创建了一个模型,以便将其展示给视图。但是,我没有得到我想要的数据。我无法弄清楚我在哪里弄错了linq。请帮忙。

This are the tables involved, the output using SQL and output using LINQ

这是SQL:

  select oh.date, oh.id, 
         od.TotalAmount, 
         CASE when oh.Discount_level = 2
            then ((od.TotalAmount / 1.12) * .2)
         END as Discount, 
         (od.TotalAmount / 1.12) as VATSale, 
         ((od.TotalAmount / 1.12) * .12) as VAT,
         CASE when oh.Discount_level = 2
            then ((od.TotalAmount / 1.12) * .8)
            when oh.Discount_level = 1
            then od.TotalAmount
         END as AmountDue
  from Order_Header oh
  inner join 
  ( 
    select Order_Header_id, SUM(price * quantity) as TotalAmount
    from Order_Details
    group by Order_Header_id
  ) od
  on oh.id = od.Order_Header_id;

我有的linq:

  var list = (from oh in db.Order_Header
                 join iq in (
                                from t in db.Order_Details
                                group t by t.Order_Header_id
                                into g
                                select new
                                {
                                    ohId = g.Key,
                                    totalAmount = ((from t2 in db.Order_Details select t2.price * t2.quantity)).Max()
                                }
                             )
                 on oh.id equals iq.ohId
                 select new Report
                 {
                     date = oh.date,
                     ohId = iq.ohId,
                     totalAmount = iq.totalAmount,
                     discount = oh.Discount_level == 2 ? (iq.totalAmount /1.12) * 2 : 0 ,
                     VATSale = iq.totalAmount / 1.12,
                     VAT = (iq.totalAmount / 1.12) * .12,
                     amountDue = oh.Discount_level == 2 ? ((iq.totalAmount / 1.12) * .8) * 2 : iq.totalAmount
                 }).ToList();

报告模型:

public class Report
{
    public DateTime? date  { get; set;  }

    public int ohId  { get; set;  }

    public double totalAmount { get; set; }

    public double discount { get; set; }

    public double VATSale { get; set; }

    public double VAT { get; set; }

    public double amountDue { get; set; }

}

1 个答案:

答案 0 :(得分:0)

假设您的POCO模型如下:

    public class Order_Header
    {
        public Guid Id { get; set; }
        public int Discount_Level { get; set; }
        public Order_Detail Order_Detail {get;set;}
    }

    public class Order_Detail
    {
        public Guid Order_Header_Id { get; set; }
        public double Price { get; set; }
        public int Quantity { get; set; }
        public Order_Header Order_Header { get; set; }
    }

并将ods作为IDbSet<Order_Detail>内的DbContext个实例。 您可以将上面的查询翻译成Lambda LINQ,就像这样。

    var odproj = ods.GroupBy(x => x.Order_Header_Id)
                    .Select(x => new { Order_Header = x.First().Order_Header,
                                       TotalAmount = x.Sum(y => y.Price * y.Quantity)})
                    .Select(x => new { Order_Header = x.Order_Header,
                                       Id = x.Order_Header.Id,
                                       TotalAmount = x.TotalAmount,
                                       Discount = (x.Order_Header.Discount_Level == 2 ? ((x.TotalAmount / 1.12) * 0.2) : 0),
                                       VATSale = (x.TotalAmount / 1.12),
                                       VAT = ((x.TotalAmount / 1.12) * 0.12),
                                       AmountDue = ((x.Order_Header.Discount_Level == 2) ? ((x.TotalAmount / 1.12) * 0.8)
                                                                                         : (x.Order_Header.Discount_Level == 1 ? x.TotalAmount : 0)
                                                   )
                     });

<强>解释 首先,我们基于Order_Detail(一个)对Order_Header(多个)进行分组,以定义单个事务(在POS系统意义上就是这样)。分组后,我们根据订单的价格和数量“计算”总金额。总价格计算在第一个Select中完成,它生成一个包含2个字段的匿名类,一个用于保存Order_Header信息,另一个用于我们想要的信息。下一个Select我们计算折扣,VATSale等 - 第一个子句中的复杂if-else。

聚苯乙烯。我还没有在EF中试过这个,我的RAM太小了,无法启动SQL Server。用谷物和盐来理解这个想法。这个问题的关键角落,我有点犹豫不决,EF是否会识别Order_Header = x.First().Order_Header。尽管如此,使用LINQ已经足够严重,可以保证您使用OUTER JOIN,但最终可能会被SQL执行计划程序删除。如果它过于复杂,只需制作一个STORED PROCEDURE并拉出edmx来映射它(等等,Code First能做到这一点吗?我真的很想知道。)