多年来我读过几个不同的来源,表明在存储数据集合时,List<T>
在插入对象时效率很高,IEnumerable<T>
最适合枚举集合。
在LINQ-to-Entities中,有AsEnumerable()
函数,它将返回IEnumerable<T>
,但在您开始枚举列表之前,它不会解析LINQ语句创建的SQL。
如果我想将LINQ中的对象存储到集合中的实体,然后再对该集合进行查询,该怎么办?
使用此策略会导致通过添加WHERE子句并分别查询每个记录来解析SQL。我特意不想要这样做,因为我试图限制网络聊天:
var myDataToLookup = context.MyData.AsEnumerable();
for(var myOtherDatum in myOtherDataList)
{
// gets singular record from database each time.
var myDatum = myDataToLookup.SingleOrDefault(w => w.key == myOtherDatum.key)
}
如何解决SQL的问题,以便myDataToLookup实际上包含内存中的数据?我试过ToArray:
var myDataToLookup = context.MyData.ToArray();
但我最近了解到它实际上使用的内存比ToList更多: Is it better to call ToList() or ToArray() in LINQ queries?
我应该使用联接吗?
var myCombinedData = from o in myOtherDataList
join d in myDataToLookup on
o.key equals d.key
select { myOtherData: o, myData: d};
我应该使用ToDictionary
并将我的密钥存储为字典的关键字吗?或者我对此过于担心?
答案 0 :(得分:1)
如果您正在使用LINQ to Entities
,那么如果ToArray
慢于ToList
,您就不必担心。它们在性能方面几乎没有差异,LINQ to Entities
本身无论如何都会成为瓶颈。
关于字典。它是一种针对按键读取而优化的结构。但是,添加新商品需要额外付费。所以,如果你会按键读取很多东西并添加不常用的新项目,那么这就是你要走的路。但说实话 - 你可能根本不应该打扰。如果数据量不够大,您就不会发现差异。
答案 1 :(得分:1)
将IEnumerable
,ICollection
和IList
/ IDictionary
视为从前一个继承的层次结构。数组在列表之上添加了一定程度的限制和复杂性。简单来说,IEnumerable
仅为您提供迭代。 ICollection
添加计数,然后IList
提供更丰富的功能,包括按索引或通过lambda表达式查找,添加和删除元素。字典通过密钥提供高效访问。数组更加静态。
那么,答案取决于您的要求。如果将数据保存在内存中并且您需要经常重新查询它,那么我通常会将实体结果转换为List。这也会加载数据。
如果通过一组键进行访问是至关重要的,那么我使用字典。
我不记得上次使用数组时除了偶尔和非常特殊的目的。
所以,不是一个直接的答案,但正如你的问题和其他答复表明没有一个答案,解决方案将是妥协。
答案 2 :(得分:0)
当我编码和测量网络上传输的性能和数据时,我会根据您上面的示例查看内容。
让我们说你的结果会返回100条记录。您的代码现在已在服务器上运行查询并执行了1秒的处理(为了参数,我将数字设置为了)。
然后你需要将它投射到一个列表,该列表将再处理1秒钟。然后,您希望查找值为1的所有记录。现在,代码将遍历整个列表以查找值为1,然后返回结果。这是让我们再说1秒钟的处理,它会找到10条记录。
您的网络将携带超过10条记录,需要3秒钟才能处理。
如果您将逻辑移动到数据层并立即搜索所需的记录,则可以节省2秒的性能,但仍然只能通过网络传输10条记录。奖金方面也是你可以使用IEnumberable作为结果,而不必将其列入一个列表。从而消除了1秒的铸造列表和1秒的迭代列表。
我希望这有助于回答你的问题。