2013-02-22 66 views
0

我使用这个表达式来获取所有产品:LINQ to SQL的嵌套式

Expression<Func<Product, ProductInCityDto>> GetAllProducts 
{ 
    get 
    { 
     return product => new ProductInCityDto 
     { 
      ProductName = product.ProductName, 
      CityName = product.Store.City.Name, 
      CountryName = product.Store.City.Country.Name, 
      ProductAvgPrice = CalculateAvg(product) 
      . 
      . 
      . 
     } 
    } 
} 

我使用的功能CalculateAvg来计算产品的平均价格。计算是分开的函数,因为我在几个地方使用这个代码。 但是,这种方法会导致多次调用数据库。 是否有可能用Linq Expression替换函数CalculateAvg,以便只有一个调用到DB?

编辑:

功能CalculateAvg看起来是这样的:

所有的
public static decimal CalculateAvg(object tempObj) 
{ 
    Product obj = tempObj as Product; 
    return Convert.ToDecimal 
      (obj.Sales.Where(n => n.type != 1) 
       .Average(n=>n.Price) 
     ); 
} 
+0

'CalculateAvg'看起来怎么样?请显示代码 – 2013-02-22 13:20:01

+0

尝试返回'IQuerable '而不是(删除'Convert.ToDecimal') – Magnus 2013-02-22 13:39:21

+0

可以发布更多的代码,你的表情看起来如何?你确定多个电话是因为这个功能吗,不是因为你的表达的其他部分可能会做某些事情吗? – Raxr 2013-02-22 13:41:15

回答

0

首先,我会重构你的功能为扩展方法,并取下转换隔离一些可能性。请记住,您必须在静态类中放置扩展方法。

public static double CalculateAvg(this Product product) 
{ 
    return product.Sales.Where(n => n.type != 1).Average(n=>n.Price); 
} 

如果这仍然会导致多次往返,请发表您的探查看到查询,所以我们可以从工作。

+0

它不起作用。同样的事情发生。生成的sql查询很简单,并且多次执行(每个产品使用不同的id)。 – Programmer 2013-02-22 14:02:05

+0

而当你只要在CalculateAvg函数中返回一个'0'(零)时,往返不会发生就是正确的? – Raxr 2013-02-22 20:45:58

+0

在这种情况下不会发生往返 – Programmer 2013-02-25 10:14:09

0

这个困难的部分不是转换到Linq表达式。困难的部分是调用表达式。这很难。但最糟糕的是,它不是类型安全的,并且涉及类似于反思的东西。

实际魔法的一部分是IQueryable.Provider.Execute(表达)..

你当然可以试试这个...但它是没有测试手段。更何况,非常难看。

Expression<Func<Product, ProductInCityDto>> GetAllProducts 
{ 
    get 
    { 
     return product => new ProductInCityDto 
     { 
      ProductName = product.ProductName, 
      CityName = product.Store.City.Name, 
      CountryName = product.Store.City.Country.Name, 
      //Bit of a hack to coerce the Provider out... 
      ProductAvgPrice = product.Sales 
        .AsQueryable.Provider 
        .Execute<double>(CalculateAvg(product), Expression.Constant(product, typeof (Product))), 
      . 
      . 
      . 
     } 
    } 
} 

public Expression<Func<Product, double>> CalculateAvg() 
{ 
    return product => product.Sales.Where(n => n.type != 1).Average(n=>n.Price); 
}