c# LINQ和涉及大型数据集的计算

本文关键字:数据集 计算 大型 LINQ | 更新日期: 2023-09-27 18:06:35

这更像是一个技术性的"如何做"或"最佳方法"问题。

我们当前需要从数据库中检索记录,将它们放入"内存"列表中,然后对数据执行一系列计算,即最大值,平均值和一些更具体的自定义统计。

将数据放入"内存中"列表不是问题,因为我们使用NHibernate作为ORM,并且它在从数据库检索数据方面做得很好。我正在寻求的建议是,我们应该如何最好地对结果数据列表进行计算。

理想情况下,我想为每个统计,MaximumValue(), AverageValueUnder100(), morecomplexatedstatistic()等创建一个方法。当然,将所需的变量传递给每个方法,并让它返回结果。这种方法也会使单元测试变得轻而易举,并为我们提供良好的覆盖率。

如果我们对每个计算执行LINQ查询,或者应该在尽可能少的LINQ查询中合并对每个统计方法的尽可能多的调用,是否会有性能影响?例如,将数据列表传递给一个名为AverageValueBelow100的方法,然后将整个数据列表传递给另一个方法AverageValueBelow50,当它们可以通过一个LINQ查询有效地执行时,这是没有多大意义的。

我们如何在不牺牲性能的情况下实现高粒度和分离?

有什么建议…这个问题够清楚吗?

c# LINQ和涉及大型数据集的计算

根据计算的复杂程度,最好在数据库中进行计算。如果非常复杂,需要将其作为对象引入,并产生这种开销,则可能希望避免对结果集进行多次迭代。您可能需要考虑使用聚合。请参阅http://geekswithblogs.net/malisancube/archive/2009/12/09/demystifying-linq-aggregates.aspx进行讨论。您将能够分别对每个聚合进行单元测试,但随后(潜在地)在单个迭代中规划多个聚合。

我不同意"在数据库中完成所有操作"是最好的。

编写良好的Linq查询将导致对数据库执行良好的SQL查询,这应该是足够好的性能(如果你不打算做dwh的东西)。这是假设你使用的是NHibernate的Linq Provider,而不是Linq to Objects。

它看起来不错,你可以很容易地改变它,并保持你的业务逻辑在一个地方。

如果这对于你的需要来说太慢了,你可能会检查创建的SQL代码并调整你的linq查询,尝试预编译它们,最后你仍然可以回去编写心爱的存储过程——并开始将你的业务逻辑扩展到所有的地方。

会影响性能吗?是的,你可能会损失几毫秒,但这值得你为分离逻辑而付出的代价吗?

要回答"我想为每个统计数据创建一个方法"的问题,我建议您构建一种统计学家类。下面是一些伪代码来表达这个想法:

class Statistician
{
    public bool MustCalculateFIRSTSTATISTIC { get; set; }   // Please rename me!
    public bool MustCalculateSECONDSTATISTIC { get; set; }  // Please rename me!
    public void ProcessObject(object Object) // Replace object and Rename
    {
        if (MustCalculateFIRSTSTATISTIC)
            CalculateFIRSTSTATISTIC(Object);
        if (MustCalculateFIRSTSTATISTIC)
            CalculateSECONDSTATISTIC(Object);
    }
    public object GetFIRSTSTATISTIC() // Replace object, Rename
    { /* ... */ }
    public object GetSECONDSTATISTIC() // Replace object, Rename
    { /* ... */ }
    private void CalculateFIRSTSTATISTIC(object Object) // Replace object
    { /* ... */ }
    private void CalculateSECONDSTATISTIC(object Object) // Replace object
    { /* ... */ }
}

如果我必须这样做,我可能会尝试使它泛型并使用委托集合而不是方法,但由于我不知道你的上下文,我将把它留给它。还请注意,我只使用对象类的对象成员,但这只是因为我不建议您使用datarow,实体或其他东西;我将把这个问题留给其他比我更了解这个问题的人!