c# - 是否在 LINQ 中使用 AsEnumerable()?

标签 c# linq linq-to-sql entity-framework-5 linq-to-objects

我知道 AsEnumerable() 用于从“LINQ to SQL”切换到“LINQ to Object”,因此我们可以在 LINQ 查询中使用一些额外的(主要是用户定义的)方法。但根据我的经验,使用 AsEnumerable() 会使查询速度变慢。在这种情况下,我可以稍后枚举该列表以应用我自己的方法,但结果仍然相当慢。

谁能提出更好的方法吗?

这是我想要做的一些代码示例?

使用 AsEnumerable():

var Data = (from r in _context.PRD_ChemProdReq.AsEnumerable()
                    //where r.RecordStatus == "NCF"
                    orderby r.RequisitionNo descending
                    select new PRDChemProdReq
                    {
                        RequisitionID = r.RequisitionID,
                        RequisitionNo = r.RequisitionNo,
                        RequisitionCategory = DalCommon.ReturnRequisitionCategory(r.RequisitionCategory),
                        RequisitionType = DalCommon.ReturnOrderType(r.RequisitionType),
                        ReqRaisedOn = (Convert.ToDateTime(r.ReqRaisedOn)).ToString("dd'/'MM'/'yyyy"),
                        RecordStatus= DalCommon.ReturnRecordStatus(r.RecordStatus),
                        RequisitionFromName = DalCommon.GetStoreName(r.RequisitionFrom),
                        RequisitionToName = DalCommon.GetStoreName(r.RequisitionTo)
                    }).ToList();

没有 AsEnumerable():

var Data = (from r in _context.PRD_ChemProdReq
                    //where r.RecordStatus == "NCF"
                    orderby r.RequisitionNo descending
                    select new PRDChemProdReq
                    {
                        RequisitionID = r.RequisitionID,
                        RequisitionNo = r.RequisitionNo,
                        RequisitionCategory = r.RequisitionCategory,
                        RequisitionType = (r.RequisitionType),
                        ReqRaisedOnTemp = (r.ReqRaisedOn),
                        RecordStatus= (r.RecordStatus),
                        RequisitionFrom = (r.RequisitionFrom),
                        RequisitionTo = (r.RequisitionTo)
                    }).ToList();

        foreach (var item in Data)
        {
            item.RequisitionCategory = DalCommon.ReturnRequisitionCategory(item.RequisitionCategory);
            item.RequisitionType = DalCommon.ReturnOrderType(item.RequisitionType);
            item.ReqRaisedOn = (Convert.ToDateTime(item.ReqRaisedOnTemp)).ToString("dd'/'MM'/'yyyy");
            item.RecordStatus = DalCommon.ReturnRecordStatus(item.RecordStatus);
            item.RequisitionFromName = DalCommon.GetStoreName(item.RequisitionFrom);
            item.RequisitionToName = DalCommon.GetStoreName(item.RequisitionTo);
        }

最佳答案

看起来您将这两个接口(interface)混淆为两个完全不同的东西。事实上,IQueryable 是从 IEnumerable 继承的,因此无论您在后者中使用什么,也可以在前者中使用,因此不需要使用 AsEnumerable

尽管这些接口(interface)的实现方式在幕后完全不同 - IEnumerable 将在内存中处理您的集合,而 IQueryable 会将查询传递给底层数据提供程序。您可以想象,如果数据库表包含数百万条记录,并且您尝试对其进行排序,DB 服务器可以非常快速地完成此操作(使用索引),因此 Queryable 将会大放异彩。对于 IEnumerable,所有数据都需要加载到计算机内存中并在那里排序。

要获得更长的答案,请在 SO 上搜索“IEnumerable IQueryable 差异”,您将看到大量详细信息:

Random Link 1 Random Link 2

更新:如果您从第二个示例中删除调用.ToList,则结果将不会自动加载到内存中。此时,您需要决定要将哪些项目存储在内存中,并仅为它们调用您的函数。

var Data = (from r in _context.PRD_ChemProdReq
           orderby r.RequisitionNo descending
           select new PRDChemProdReq
           {
               // do your initialization
           });

var subsetOfData = Data.Take(100).ToList(); // Now it's loaded to memory
foreach (var item in subsetOfData)
{
    item.RequisitionCategory = DalCommon.ReturnRequisitionCategory(item.RequisitionCategory);
    item.RequisitionType = DalCommon.ReturnOrderType(item.RequisitionType);
    item.ReqRaisedOn = (Convert.ToDateTime(item.ReqRaisedOnTemp)).ToString("dd'/'MM'/'yyyy");
    item.RecordStatus = DalCommon.ReturnRecordStatus(item.RecordStatus);
    item.RequisitionFromName = DalCommon.GetStoreName(item.RequisitionFrom);
    item.RequisitionToName = DalCommon.GetStoreName(item.RequisitionTo);
}

现在,如果您确实需要为所有数据分配这些属性,并且数据可以是任意大,那么您需要制定一个策略来实现这一点。非常简单的选择是将它们保存到数据库中的一个新表中,然后处理的数据的大小将仅受数据库容量的限制。

关于c# - 是否在 LINQ 中使用 AsEnumerable()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31129476/

相关文章:

c# - 我如何保留稍后将传递给 OrderBy 或 LoadWith 函数的 lambda 表达式的引用?

c# - 如何将 wpf 调度程序转换为 winforms

c# - 字符串与 StringBuilder

c# - Linq FindWhere 子句和 bool 过滤器?

c# - 我应该什么时候处理数据上下文

linq - 如何使用 LINQ to SQL 预先加载同级数据?

c# - 使用 guid 进行测试...如何将变量设置为 Guid?

c# - 使用相同数量的参数和相同类型重载方法

c# - 用于网络的 SQL

c# - 使用 Linq 选择类的属性以返回 IEnumerable<T>