1

我已经为我的 EF6 数据库模型配置了一个 RESTier 接口,并定义了一个将国家代码作为参数的操作。

此操作返回公司库存中的产品列表(InvMaster 类型的对象),每个 InvMaster 对象具有来自各种供应商价目表的一个或多个价格。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
                }
            ]
        }
    ]
}

在操作中,我使用传入的国家/地区代码以及其他一些逻辑来确定可用价格的优先级,并返回库存商品以及一系列订购价格。但是,我只希望对客户端应用程序上显示的项目执行此排序逻辑(即:在应用 $filter、$skip 和 $top 逻辑之后)

例如,如果在我的客户端应用程序中,用户每页选择 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