簡體   English   中英

如何使用EF5填充擴展方法並返回IQueryable(無循環)

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM