[英]How can I populate Extended Methods with EF5 and return IQueryable (without looping)
我是實體框架的新手。 這是我第一個使用它的項目。
我創建了一個新類,將新的屬性擴展為“商人”實體,這些屬性大多是計算得出的總數。 我想不出用數據填充這些新屬性的最佳方法。 我正在使用breeze.js來查詢iQueryable端點,因此我需要保持此功能完整。
我找到了以下解決方案,但是它很慢,因為我必須遍歷每條記錄。 盡管我已經實現了輕輕松松的分頁,但是循環仍然會命中每條記錄,盡管它只會返回一頁。 我想這就是實體框架的工作方式。 我的問題是如何填充擴展屬性而不循環?
這是我的代碼,但是很慢。 我可以消除此循環,並用值填充該擴展屬性嗎?
[HttpGet]
public IQueryable<Merchant> MerchantList()
{
IQueryable<Merchant> items = _repo.Context.Merchants;
foreach (var item in items)
{
// Total Stores
item.TotalStores = myMethod(item.MerchantUID);
}
return items;
}
從外觀上看,您正在遍歷整個表中有價值的數據,這是某人偶然獲得某些行的機會。 我對Breeze
並不熟悉,但是我曾經與OData
合作過,所以希望該解決方案對您OData
。
我建議您停止公開IQueryable<>
並在內部管理查詢。 這將使您可以將附加信息僅添加到要返回給客戶端的那些記錄。 以下是一些粗略的代碼,可為您指明正確的方向:
[HttpGet]
public PageResult<Merchant> MerchantList(
ODataQueryOptions<Merchant> queryOptions)
{
var t = new ODataValidationSettings() { MaxTop = 25 };
var s = new ODataQuerySettings() { PageSize = 25 };
queryOptions.Validate(t);
IEnumerable<Merchant> results =
(IEnumerable<Merchant>)queryOptions.ApplyTo(_repo.Context.Merchants, s);
int skip = queryOptions.Skip == null ? 0 : queryOptions.Skip.Value;
int take = queryOptions.Top == null ? 25 : queryOptions.Top.Value;
long? count = Request.GetInlineCount();
List<Merchant> pageOfResults = results.Skip(skip).Take(take).ToList();
PageResult<Merchant> page =
new PageResult<Merchant>(
pageOfResults,
Request.GetNextPageLink(),
Request.GetInlineCount());
foreach (var item in page)
{
// Total Stores
item.TotalStores = myMethod(item.MerchantUID);
}
return page;
}
和using
s
using System.Web.Http;
using System.Web.Http.OData;
using System.Web.Http.OData.Builder;
using System.Web.Http.OData.Query;
謝謝大家的指導。 最接近的建議是關於使用oData的建議。 我研究了熱切的加載,但這似乎適用於連接實體,並且這些屬性無法合並。 我可能會對“ include”進行更多的研究,以確定它是否可以用於加載單個屬性,但是我找不到使用該方法的任何文檔。 與之接近的另一件事是投影,但是EF不允許將其投影到同一類型。 我本可以將其投影到局部類中,但隨后我會松散微風所需的MetaData。 如果不是微風吹拂,那將是一個非常不錯的解決方案。 最后,盡管Breeze確實支持oData,但它有太多限制(例如無法緩存),所以我想繼續使用IQueryable。
這就是我想出的。 現在,它僅循環瀏覽當前頁面,但仍可對主查詢進行計數,因此Breeze可以在客戶端上進行頁面調度。 這一切皆有可能,因為Breeze允許我發送get參數,以便將分頁卸載到服務器。 這花費了大量的研究,但仍然不是很完美,但是它的加載速度非常快,因此我現在必須繼續。
[HttpGet]
[BreezeQueryable]
public QueryResult MerchantList(int take, int skip)
{
IQueryable<Merchant> main = _repo.Context.Merchants.OrderBy(m => m.MerchantUID);
IQueryable<Merchant> items = main.Skip(skip).Take(take);
foreach (var item in items)
{
// Total LifetimeVal
item.LifetimeVal= TotalLifetimeVal(item.MerchantUID);
// Total Stores
item.TotalStores = TotalStores(item.MerchantUID);
}
// return items;
return new QueryResult
{
InlineCount = main.Count(),
Results = items.ToList()
};
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.