0

この式を使用して、すべての製品を取得しています。

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 を使用して、製品の平均価格を計算しています。このコードをいくつかの場所で使用しているため、計算は別の関数になっています。ただし、このアプローチでは、データベースへの複数の呼び出しが発生します。DBへの呼び出しを1回だけにするために、関数CalculateAvgをLinq Expressionに置き換えることは可能ですか?

編集:

関数 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)
          );
}
4

2 に答える 2

0

まず、関数を拡張メソッドにリファクタリングし、変換を削除していくつかの可能性を分離します。拡張メソッドを静的クラスに配置する必要があることに注意してください。

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

これでも複数のラウンド トリップが発生する場合は、プロファイラーに表示されるクエリを投稿してください。

于 2013-02-22T13:54:21.423 に答える
0

これの難しい部分は、Linq 式への変換ではありません。難しい部分は、式の呼び出しです。これは難しいです。しかし最悪なのは、タイプセーフではなく、リフレクションに似たものを含んでいるということです。

実際の魔法の部分は IQueryable.Provider.Execute(Expression) です。

あなたは確かにこれを試すことができます...しかし、それは決してテストされていません. 言うまでもなく、かなり醜いです。

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);
}
于 2013-02-25T14:14:34.937 に答える