1

EF6 データベース モデルへの RESTier インターフェイスを構成し、国コードを引数として取る操作を定義しました。

この操作は、会社の在庫 (タイプ InvMaster のオブジェクト) 内の製品のリストを返します。各 InvMaster オブジェクトには、さまざまなサプライヤー価格リストからの 1 つ以上の価格があります。JSON モデルは次のようになります。

{
     @ odata.context = http: //localhost:60414/restier/$metadata#InvMaster(StockCode,Description,LongDesc,ProductClass,InvMaster_,Gw_ItemPrice,InvMaster_(Brand,Manufacturer),Gw_ItemPrice(ItemPriceID,PriceListed,PriceListID,Gw_PriceList,Gw_PriceList(ApSupplier(Currency,SupplierName))))
        "@odata.count": 104,
    "value":
    [{
            "StockCode": "AVI000001",
            "Description": "Bakers Choice Assorted",
            "LongDesc": "12 x 200 g",
            "ProductClass": "01010SnackSweetBisc",
            "InvMaster_": {
                "Brand": "Bakers",
                "Manufacturer": "National Brands"
            },
            "Gw_ItemPrice":
            [{
                    "PriceListed": 308.6000,
                    "ItemPriceID": 1
                }, {
                    "PriceListed": 239.2200,
                    "ItemPriceID": 2
                }
            ]
        }
    ]
}

オペレーション内で、渡された国コードとその他のロジックを使用して、利用可能な価格に優先順位を付け、注文された価格の配列で在庫品目を返します。ただし、クライアント アプリケーションに表示される項目に対してのみ、この並べ替えロジックを実行したいと考えています (IE: $filter、$skip、および $top ロジックを適用した後)。

たとえば、クライアント アプリケーションで、ユーザーが 1 ページあたり 50 項目を選択した場合、$top=50&$skip=?? 私の操作への呼び出しとともにクエリオプションとして送信されます。最終的には正しいデータが返されますが、私の操作では、在庫内のすべてのアイテムと価格の並べ替えを反復処理しており、最終的にクエリ オプションを使用して、要求されたエントリのみを除外しています。計算を実行する前にクエリ オプションを適用する必要があります。そうしないと、価格を含むアイテムが要求されるたびに無駄な作業を大量に実行する、非常に遅い操作になります。これを達成する方法についての私の理解は、操作内でクエリオプションを使用することです...これらはOdataQueryOptionsになると思います...しかし、これらにアクセスする方法がわかりません。助けてください。

操作の基本構造は次のとおりです。

    [Operation(EntitySet = "InvMaster")]
    [EnableQuery]
    public IQueryable<InvMaster> GetItemsWithPrioritisedPrices(string destination)
    {
        // Get the inventory items which are being requested
        // TODO: How do I use the ODataQueryOptions from the query?!? Worried about performance.
        // Surely I need to apply $top, $skip to the query below?!?!?!?!
        // This operation will be perfectly happy if we only have to deal with 10, 20 or even 50 inventory items at a time.
        // Otherwise we land in the dwang.
        var items = ModelContext.InvMaster
                         .Include(i => i.InvMaster_)
                         .Include(i => i.InvAltSupplier)
                         //.Take(10)
                         .ToList()
                         .AsQueryable();
                         // TODO: Check what is hitting the database from this query.

        var itemsPricesOrdered = new List<InvMaster>();

        foreach (var item in items)
        {
            var pricesOrdered = new List<Gw_ItemPrice>();
            // List to hold all available suppliers for each stock item.
            var validSuppliers = new List<string>();

            // Stock item has Default Supplier and alternate suppliers (InvAltSupplier).
            // First add the alternate Suppliers.
            foreach (var supplier in item.InvAltSupplier)
            {
                validSuppliers.Add(supplier.Supplier);
            }

            // Finally add the default supplier for the item.
            validSuppliers.Add(item.Supplier);

            try
            {
                // Get available price lists for this stock code and supplier
                var prices = ModelContext.Gw_ItemPrice
                            //.Where(e => e.Gw_PriceList.Supplier == supplier)
                            .Where(e => e.StockCode == item.StockCode)
                            .Where(e => e.Gw_PriceList.Gw_PriceStatus.PriceStatusID == 3)
                            .Include(e => e.Gw_PriceList)
                            .Include(e => e.Gw_PriceList.ApSupplier)
                            .ToList();

                foreach (var price in prices)
                {
                    // Initialise warning flags to false.
                    price.MarketRestricted = false;
                    price.DateExpired = false;
                    price.DefaultSupplier = false; //currently not used.

                    // Do the logic to order prices as required.
                    // should only order prices for the entries that need to be returned.
                }
4

0 に答える 0