我知道AsEnumerable()用于从"LINQ“切换到"LINQ”,因此我们可以在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);
}发布于 2015-06-30 06:06:11
好了,伙计们,我注意到了你们所有人的不同观点&我想出了以下几点:
var Data = (from r in _context.PRD_ChemProdReq.AsEnumerable()
//where r.RecordStatus == "NCF"
join rf in _context.SYS_Store on (r.RequisitionFrom==null?0: r.RequisitionFrom) equals rf.StoreID into requisitionfrom
from rf in requisitionfrom.DefaultIfEmpty()
join rt in _context.SYS_Store on (r.RequisitionTo == null ? 0 : r.RequisitionTo) equals rt.StoreID into requisitionto
from rt in requisitionto.DefaultIfEmpty()
orderby r.RequisitionNo descending
select new PRDChemProdReq
{
RequisitionID = r.RequisitionID,
RequisitionNo = r.RequisitionNo,
RequisitionCategory = DalCommon.ReturnRequisitionCategory(r.RequisitionCategory),
RequisitionType = r.RequisitionType == "UR" ? "Urgent" : "Normal",
ReqRaisedOn = (Convert.ToDateTime(r.ReqRaisedOn)).ToString("dd'/'MM'/'yyyy"),
RecordStatus = (r.RecordStatus=="NCF"? "Not Confirmed": "Approved"),
RequisitionFromName = (rf==null? null: rf.StoreName),
RequisitionToName = (rt == null ? null : rt.StoreName)
});首先,我删除了ToList(),它只执行在调用AsEnumerable()时已经完成的查询。没有点两次执行相同的查询。另外,我在select块中的自定义方法调用也起到了减缓事情的主要作用。我尽量减少方法调用,而在可能的情况下使用join。它会让事情变得更快。谢谢大家。
发布于 2015-06-30 04:50:07
看起来你把这两个接口混淆成两个完全不同的东西。事实上,IQueryable是从IEnumerable继承而来的,所以无论对后者使用什么都可以使用前者,所以不需要使用AsEnumerable。
在幕后,尽管这些接口的实现非常不同-- IEnumerable将在内存中处理您的集合,IQueryable将把查询传递给底层数据提供程序。您可以想象,如果数据库表包含数百万条记录并试图对其进行排序,DB服务器可以非常快地(使用索引)进行排序,这样Queryable就会发光。对于IEnumerable,所有数据都需要加载到计算机内存中并在那里进行排序。
关于搜索"IEnumerable IQueryable difference"的更长的答案,您将看到大量详细信息:
更新:如果从第二个示例中删除调用.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);
}现在,如果您实际上需要为所有的分配这些属性--您的数据和数据可以是任意大的--那么您需要制定一种策略来实现它。非常简单的选项是将它们保存到一个新表中,然后处理数据的大小将仅受数据库容量的限制。
发布于 2015-06-30 04:47:19
如果在AsEnumerable()之后添加任何查询元素,则它的速度会更慢。
即使AsEnumerable()不直接执行查询,在之后应用where或orderby AsEnumerable()意味着Sql将获取所有项,然后对内存中的集合应用筛选和排序。
简言之:
AsEnumerable() =在SQL中进行筛选和排序AsEnumerable(),然后将Where或orderby =应用于引入内存的整个集合。您只能在内存中的集合上运行用户定义的函数(因为您的Linq到SQL将无法将您的函数解释为SQL代码)。因此,您的第二个代码段(没有AsEnumerable())可能是最好的。
唯一的其他选择是在SQL本身中应用用户定义的函数。
https://stackoverflow.com/questions/31129476
复制相似问题