refactoring LINQ IQueryable expression to remove duplicated portions of queries

前端 未结 3 758
滥情空心
滥情空心 2021-02-09 11:40

I have some linq queries that have redundancy I\'d like to factor out a single piece of code. These are join experssions that are IQueryable, and its important I don\'t cause t

3条回答
  •  谎友^
    谎友^ (楼主)
    2021-02-09 12:32

    Sorry to answer my own question, but I found a good solution. I think though that depending on what you're trying to do, there are different way to factor out different LINQ expressions without evaluating the IQueryable. So I hope people share alternative solutions.

    My solution was to create a "view" for the factored out query. I call it a view because it has a lot in common with a SQL view (from the perspective of a LINQ client). Unlike a SQL view though, it cannot be indexed or have columns persisted. So using this view becomes a bottleneck, it would be appropriate to use an actual SQL view.

    static public class MyDataContextExtension
    {
        // The view exposes OrderSummary objects
        public class OrderSummary
        {
            public OrderID { get; set; }
            public string FirstProductListed { get; set; }
        }
    
        static public IQueryable OrderySummaryView(this MyDataContext db)
        {
             return (
                  from O in db.Orders
                  join OD in db.OrderDetails on O.OrderID equals OD.OrderID into OrderDetails
                  let AProductBought = OrderDetails.First().Select(OD => OD.Product.ProductName)
                  let TotalCost = OrderDetails.Aggregate(0
                  select new OrderSummary()
                  {
                      OrderID = OD.OrderID,
                      FirstProductListed = AProductBought.FirstOrDefault()
                  };
        }
    }
    

    With this, I can factor out the duplicated portion of the query, replacing the original query with the following:

    var result = 
    from T in db.Transactions
    join OS in db.OrderSummaryView() on T.OrderID equals OS.OrderID
    select new
    {
      TransactionID = T.TransactionID,
      OrderID = T.OrderID,
      FirstProductBought = OS.FirstProductListed
    };
    

    You can imagine other columns being added... I think one cool thing is that if you add extra columns but don't use them in your final select, LINQ won't actually query for those things from the database.

提交回复
热议问题