7

Linqクエリの「選択」フィールドで定期的に返したい特定の計算フィールドがあります。たとえば、今年の顧客注文合計と、顧客の他の人口統計情報です。

public class Customer {
  public decimal TotalPurchasesThisYear(MyDataContext db) {
    return db.Orders.Where(o => o.CustomerID == ID)
                    .Sum(o => o.OrderTotalAmt);
  }
}

public class SomeReport {
  public void GetCustomerInfoBySalesperson(long salespersonID) {
    using (var db = new MyDataContext()) {
      var q = db.Customers.Where(c => c.SalespersonID == salespersonID)
                          .Select(c => new { c.Name, c.Address, ThisYearPurchases = c.TotalPurchasesThisYear(db) })
                          .ToList();
      // etc..
    }
  }
}

TotalPurchasesThisYear明らかに、 SQL 変換がないため、これは機能しません。しかし、その中のすべてに SQL 変換があります。多くの場所で同じ計算を行っているため、そのコードをクエリに直接含めたくありません。私の直感では、これは an を使用して実行する必要がありますが、いじってExpressionみましたが、正しい構文を完全に理解することはできません。

誰か助けて?ありがとう!

4

2 に答える 2

0

OK、これを行う 1 つの方法を見つけましたが、それが最善の方法かどうかはわかりません。

public class CustomerOrderInfo {
  public long CustomerID;
  public decimal TotalPurchases;
}

public class Customer {
  public static Expression<Func<Customer, CustomerOrderInfo>> GetCustomerOrderInfo() {
    return c => new CustomerOrderInfo {
                  CustomerID = c.ID,
                  TotalPurchases = c.Orders.Where(o => o.OrderDate.Year == DateTime.Now.Year)
                                    .Sum(o => o.OrderTotalAmt)
                };
  }
}

public class SomeReport {
  public void GetCustomerInfoBySalesperson(long salespersonID) {
    using (var db = new MyDataContext()) {
      var q = db.Customers
                .Join(db.Customers.Select(Customer.GetCustomerOrderInfo()),
                      c => c.ID, i => i.CustomerID,
                      (c, i) => new { c.Name, c.Address, i.TotalPurchases })
                .ToList();
  // etc..
    }
  }
}

それは機能します...しかし、基礎となるSQLは、ネストされたクエリの結合で終わります。これは私の理想ではありません。基になる SQL が次のような単純なものであることを確認したいと思います。

select c.Name, c.Address, sum(o.OrderTotalAmt) TotalPurchases
from Customer c 
left join [Order] o on o.CustomerID = c.ID
where Year(o.OrderDate) = @year
group by c.Name, c.Address
于 2013-04-09T09:02:06.393 に答える
0
List<Parent> myParents = new List<Parent>
                                         {
                                             new Parent() 
                                             {
                                                 Prop1 = "1", 
                                                 Prop2 = "2",
                                                 Prop3 = "3", 
                                                 Children = new List<Child>()
                                                        {
                                                            new Child(){ Prop1 = 1, Prop2 = 2, Prop3 = 3 },
                                                            new Child(){ Prop1 = 21, Prop2 = 22, Prop3 = 23 },
                                                            new Child(){ Prop1 = 31, Prop2 = 32, Prop3 = 33 }
                                                        }
                                             }, 
                                         };

            Expression<Func<Parent, int>> GetChildSum =
                p => p.Children.Where(c => c.Prop1 > 0).Sum(o => o.Prop2);

            var v = myParents.Where(w => w.Prop1 == "1").Select(p => GetChildSum.Compile().Invoke(p)).ToList();

            Console.WriteLine(v.First());

            //output is 56
于 2013-04-18T13:24:57.957 に答える