用于存储从LINQ到实体的数据的最有效集合?

时间:2017-02-13 21:30:53

标签: c# entity-framework linq

多年来我读过几个不同的来源,表明在存储数据集合时,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并将我的密钥存储为字典的关键字吗?或者我对此过于担心?

3 个答案:

答案 0 :(得分:1)

如果您正在使用LINQ to Entities,那么如果ToArray慢于ToList,您就不必担心。它们在性能方面几乎没有差异,LINQ to Entities本身无论如何都会成为瓶颈。

关于字典。它是一种针对按键读取而优化的结构。但是,添加新商品需要额外付费。所以,如果你会按键读取很多东西并添加不常用的新项目,那么这就是你要走的路。但说实话 - 你可能根本不应该打扰。如果数据量不够大,您就不会发现差异。

答案 1 :(得分:1)

IEnumerableICollectionIList / IDictionary视为从前一个继承的层次结构。数组在列表之上添加了一定程度的限制和复杂性。简单来说,IEnumerable仅为您提供迭代。 ICollection添加计数,然后IList提供更丰富的功能,包括按索引或通过lambda表达式查找,添加和删除元素。字典通过密钥提供高效访问。数组更加静态。

那么,答案取决于您的要求。如果将数据保存在内存中并且您需要经常重新查询它,那么我通常会将实体结果转换为List。这也会加载数据。

如果通过一组键进行访问是至关重要的,那么我使用字典。

我不记得上次使用数组时除了偶尔和非常特殊的目的。

所以,不是一个直接的答案,但正如你的问题和其他答复表明没有一个答案,解决方案将是妥协。

答案 2 :(得分:0)

当我编码和测量网络上传输的性能和数据时,我会根据您上面的示例查看内容。

让我们说你的结果会返回100条记录。您的代码现在已在服务器上运行查询并执行了1秒的处理(为了参数,我将数字设置为了)。

然后你需要将它投射到一个列表,该列表将再处理1秒钟。然后,您希望查找值为1的所有记录。现在,代码将遍历整个列表以查找值为1,然后返回结果。这是让我们再说1秒钟的处理,它会找到10条记录。

您的网络将携带超过10条记录,需要3秒钟才能处理。

如果您将逻辑移动到数据层并立即搜索所需的记录,则可以节省2秒的性能,但仍然只能通过网络传输10条记录。奖金方面也是你可以使用IEnumberable作为结果,而不必将其列入一个列表。从而消除了1秒的铸造列表和1秒的迭代列表。

我希望这有助于回答你的问题。