我已经为我的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
}
]
}
]
}
在操作中,我使用传入的国家/地区代码,以及一些其他逻辑来确定可用价格的优先顺序,并使用一系列有序价格返回库存物品。但是,我只希望对客户端应用程序上显示的项目执行此排序逻辑(IE:应用$ 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.
}