实体框架Linq,左连接和包含SUM和计数的组

时间:2017-10-26 00:22:35

标签: c# mysql entity-framework linq entity

我需要一些帮助才能将SQL转换为Linq。它在MySQL中非常直接......

Table: customers
ID  Name    
1   Bill
2   John

Table: purchases
ID  CustomerID  CompletedTransaction
1   1           False
2   2           True
3   1           True
4   1           True


    SELECT  c.ID
        c.Name,
        COUNT(p.ID) AS TotalPurchases,
        SUM(CASE WHEN p.CompletedTransaction = TRUE THEN 1 ELSE 0 END) AS                       TotalCompleted
    FROM customers c
    LEFT JOIN purchases p ON c.ID = p.CustomerID
    GROUP BY c.ID

Expected Result:
1, Bill, 3, 2
2, John, 1, 1

我已经看到了一些关于如何在Linq中实现左连接的示例,但我不确定如何在此包含SUM和Count。我在Linq中看到了从组密钥中选择返回字段的示例。这是否意味着如果我在客户表格中有更多字段,例如地址和其他我想要返回的联系方式,我是否必须将它们包含在联接中才能选择它们?希望这是有道理的。感谢任何可能使我指向正确方向的帮助或链接。

由于

2 个答案:

答案 0 :(得分:2)

以下是样本

class Program
    {
        static void Main(string[] args)
        {

            List<Customers> customers = new List<Customers>();
            customers.Add(new Customers() { ID = 1, Name = "Bill" });
            customers.Add(new Customers() { ID = 2, Name = "John" });

            List<Purchases> purchases = new List<Purchases>();
            purchases.Add(new Purchases() { ID = 1, CustomerID = 1, CompletedTransaction = false });
            purchases.Add(new Purchases() { ID = 2, CustomerID = 2, CompletedTransaction = true });
            purchases.Add(new Purchases() { ID = 3, CustomerID = 1, CompletedTransaction = true });
            purchases.Add(new Purchases() { ID = 4, CustomerID = 1, CompletedTransaction = true });

            IEnumerable<JoinResult> results = from c in customers
                                       join p in purchases
                                       on c.ID equals p.CustomerID
                                       group new { c, p } by new {p.CustomerID, c.Name} into r
                                       select new JoinResult
                                       {
                                           CustomerID = r.Key.CustomerID,
                                           CustomerName = r.Key.Name,
                                           TotalPurchases = r.Count(),
                                           TotalCompleteTransaction = r.Where(s=> s.p.CompletedTransaction).Count()
                                       };

            foreach(JoinResult r in results)
            {
                Console.WriteLine($"CustomerID : {r.CustomerID} | Name : {r.CustomerName} | TotalPurchases : {r.TotalPurchases} | TotalCompleteTransaction : {r.TotalCompleteTransaction}");
            }

            Console.ReadKey();
        }
    }

    class Customers
    {
        public int ID { get; set; }
        public string Name { get; set; }
    }

    class Purchases
    {
        public int ID { get; set; }
        public int CustomerID { get; set; }
        public bool CompletedTransaction { get; set; }
    }

    class JoinResult
    {
        public int CustomerID { get; set; }
        public string CustomerName { get; set; }
        public int TotalPurchases { get; set; }
        public int TotalCompleteTransaction { get; set; }
    }

结果 enter image description here

答案 1 :(得分:1)

expr = :(1+2*3)
typeof(expr)
fieldnames(expr)
expr.head
expr.args

# full solution
function bracketit(expr)
  if expr isa Symbol
    return string(expr)
  elseif expr isa Expr
    if expr.head == :call
      return string("(",bracketit(expr.args[2]),expr.args[1],bracketit(expr.args[3]),")")
    elseif expr.head == :comparison
      return string("(",bracketit.(expr.args)...,")")
    end
  else
    return(string(expr))
  end
end

exprA = :(3 - 4 > 1 & 2 + 2 == 4 | 10 - 5 > 2) 
bracketit(exprA) #((3-4)>((1&2)+2)==((4|10)-5)>2)

exprB = :(2 + 9 - 8 * 8 ^ 7 / 2 == 8 + 8 / 1 ^ 2) #(((2+9)-((8*(8^7))/2))==(8+(8/(1^2))))
bracketit(exprB)