如何提高EF中的AsEnumerable性能

时间:2014-02-10 16:08:08

标签: c# .net linq entity-framework

我在vs2012上工作。

我的edmx中有1对多的映射表结构。

var query = (
                    from bm in this.Context.BilBillMasters.AsEnumerable ()

                        join g in
                        (
                            from c in this.Context.BilBillDetails.AsEnumerable ()
                            group c by new { c.BillID }
                        )
                    on bm.BillID equals (g == null ? 0 : g.Key.BillID) into bDG
                    from billDetailGroup in bDG.DefaultIfEmpty()


                    where bm.IsDeleted == false
                    && (companyID == 0 || bm.CompanyID == companyID)
                    && (userID == 0 || bm.CustomerID == userID)
                    select new
                    {
                        bm.BillID,
                        BillNo = bm.CustomCode,
                        bm.BillDate,
                        BillMonth = bm.MonthFrom,
                        TransactionTypeID = bm.TransactionTypeID ?? 0,
                        CustomerID = bm.CustomerID,
                        Total = billDetailGroup.Sum(p => p.Amount),//group result


                        bm.ReferenceID,
                        bm.ReferenceTypeID

                    }
                    );






This method is taking close 30 seconds to return back the result in the first run.

不确定是什么问题。 我尝试获取结果列表并尝试了也很慢的elementAt(0)。

1 个答案:

答案 0 :(得分:4)

只要您使用AsEnumerable,您的查询就会停止为“可查询”。这意味着您正在做的是下载整个BilBillMastersBilBillDetails表,然后对应用程序中的那些表进行一些处理,而不是在SQL服务器上。这肯定会很慢。

显而易见的解决方案显而易见 - 不要使用AsEnumerable - 它基本上将处理从SQL服务器(具有所有数据和索引等)移动到您的应用程序服务器(它既没有也必须得到来自数据库服务器的数据;所有数据)。

至少,您希望尽可能地限制下载的数据量,即。例如,在使用CompanyID之前按CustomerIDAsEnumerable过滤表格。但是,总的来说,我认为没有理由不能在SQL服务器上完全执行查询 - 出于多种原因,这通常是首选解决方案。

总的来说,听起来好像你正在使用AsEnumerable来解决另一个问题,但这几乎肯定是一个糟糕的解决方案 - 至少在使用AsEnumerable之前没有进一步过滤数据。