2016-12-07 8 views
1

こんにちはlinqに下のクエリを翻訳することは可能ですか? ... 私はエンティティフレームワークのコアを使用しており、ストアドプロシージャを使用しようとしましたが、ストアドプロシージャのメタデータに適用されるモデルを作成する必要があるようです。だから私はこのようなクエリがlinqに翻訳できるので、私は別のデータベースモデルを作成する必要はありませんかどうかを理解しようとしています。linqサブクエリ結合とグループ

SELECT 
    Stock.stockID ProductID, 
    stockName ProductName, 
    categoryName ProductCategory, 
    typeName ProductType, 
    sizeName ProductSize, 
    currentQuantity CurrentQuantity, 
    standardQuantity QuantityPerBox, 
    CONVERT(VARCHAR(255),CONVERT(INT,Stock.price)) AvgUnitCost, 
    CONVERT(VARCHAR(255),CONVERT(INT,x.lastUnitCost)) LastOrderUnitCost, 
    CONVERT(VARCHAR(10),CONVERT(DATE,x.lastOrderDate)) LastOrderDate 
FROM dbo.Stock 
LEFT JOIN 
(
SELECT stockID,unitPrice lastUnitCost ,orderDate lastOrderDate, ROW_NUMBER() OVER (PARTITION BY stockID ORDER BY orderDate DESC) rn FROM dbo.SalesOrder 
    JOIN dbo.SalesOrderDetail ON SalesOrderDetail.salesOrderID = SalesOrder.salesOrderID 
WHERE customerID = @customerID AND salesStatus = 'S' 
) x ON x.stockID = Stock.stockID AND rn = 1 
LEFT JOIN dbo.StockCategory ON StockCategory.stockCategoryID = Stock.stockCategoryID 
LEFT JOIN dbo.StockType ON StockType.stockTypeID = Stock.stockTypeID 
LEFT JOIN dbo.StockSize ON StockSize.stockSizeID = Stock.stockSizeID 
WHERE disStock = 0 

答えて

1

ほとんどすべてが可能です。パフォーマンスには注意が必要です。これらのクエリを書き直すことは容易であるあなたが見ることができるように

var query = 
    from stock in db.Stocks 
    join x in (
     from grp in (
     from so in db.SalesOrders 
     join sod in db.SalesOrderDetails on so.SalesOrderId equals sod.SalesOrderId 
     where so.CustomerId == customerId && so.SalesStatus == "S" 
     orderby so.OrderDate descending 
     select new { 
      sod.StockId, 
      LastUnitCost = sod.UnitPrice, 
      LastOrderDate = so.OrderDate 
     } into inner 
     group inner by inner.StockId) 
     select grp.Take(1)) on x.StockId equals stock.StockId into lastStockSales 
    from x in lastStockSales.DefaultIfEmpty() 
    join sc in db.StockCategories on stock.StockCatergotyId equals sc.StockCategoryId into scLeft 
    from sc in scLeft.DefaultIfEmpty() 
    join st in db.StockTypes on stock.StockTypeId equals st.StockTypeId into stLeft 
    from st in stLeft.DefaultIfEmpty() 
    join ss in db.StockSizes on stock.StockSizeId equals ss.StockSizeId into ssLeft 
    from ss in ssLeft.DefaultIfEmpty() 
    where stock.DisStock == 0 
    select new MyDTO { 
     ProductId = stock.StockId, 
     ProductName = stock.StockName, 
     ProductType = st.TypeName, 
     ProductSize = ss.SizeName, 
     CurrentQuantity = stock.CurrentQuantity, 
     QuantityPerBox = stock.StandardQuantity, 
     AvgUnitCost = stock.Price, 
     LastOrderUnitCost = x.LastUnitCost, 
     LastOrderDate = x.LastOrderDate 
    }; 

は、私は少しにLINQの観点からサポートされていませんROW_NUMBER() OVER (PARTITION...ので、在庫品目の最新の売上高を取得する方法についてのロジックを変更しなければなりませんでした。繰り返しますが、クエリを書き換えるときのパフォーマンスを考慮する必要があります。

これが役に立ちます。

+0

うわー..これは本当に助けになる!パフォーマンスを考慮すると、ストアドプロシージャで使用できる別のモデルをコンテキストで作成する方がよいでしょうか?問題は私が持っている私はデータベースの最初のアプローチを使用していると私はテーブルを作成し、モデルでは、SQLデータベースのこのテーブルを意味することを反映することを意味しているコードでモデルを作る目的のために作成される... – superted

+0

私はあなたが話しているデータの量に依存していると言います。このLINQクエリが生のクエリに近いかどうかを確認するために、いくつかのパフォーマンステストを行うことができます。 'ROW_NUMBER()...'はより良いパフォーマンスを提供するかもしれませんが、そうではありません。いくつかのテストを行い、違いを見てください。私の答えはちょうどC#から豊かなクエリを表現できる方法を示しています。あなたのアプリケーションは、最良のアプローチが何であるかを指示します。 EFはツール(素晴らしいもの)ですが、唯一のものではありません。ツールを混在させることもできますが、それは悪い方法ではありません。私はエンドユーザーに最高の体験を提供するために何度もやってきました。 –

+0

ストアprocの結果を扱う別のモデルを追加しなければならないという点では、現在の唯一の解決策になります。近い将来、EF 6が 'Database.SqlQuery (...)'メソッドを提供しているのと同じように、未処理のSQLサポートが追加されることを期待しています。 –

関連する問題