我已经为我的 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.
}