1

I have configured a RESTier interface to my EF6 database model and have defined an operation which takes country code as an argument.

This operation returns a listing of products in the company inventory (objects of type InvMaster), each InvMaster object has one or more prices from various supplier price lists. The JSON model looks like this:

{
     @ 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
                }
            ]
        }
    ]
}

Within the operation I use the country code passed in, as well as some other logic to prioritize the the available prices and return the inventory items back with an array of ordered prices. However, I only wish to perform this sorting logic on the items displayed on the client application (IE: after applying the $filter, $skip and $top logic)

For example, if on my client application, the user selects 50 items per page, then $top=50&$skip=?? would be sent through as query options along with the call to my operation. Ultimately, the correct data is sent back, but in my operation, I am iterating through every single item in my inventory and sorting prices, and then the query options are finally being used to filter out only the requested entries. I need the query options to be applied before performing the calculations, otherwise this is a terribly slow operation that does a whole bunch of useless work each time items with prices are requested. My understanding of how this must be achieved is to use the query options inside the operation... I imagine these would be OdataQueryOptions... but I have no idea how these can be accessed. Please help.

Here is the basic structure of the operation:

    [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.
                }
A. Minnitt
  • 13
  • 4

0 Answers0