2

我正在为报告模型(SQL Server Reporting Services)创建数据源。 这些报告需要大量的连接和计算(比方说,计算像这样花费的金钱参数,即数量A和数量B)......所有这些涉及子对象。在Linq/Lambda中写入存储过程(单元可测试但存储过程存储过程)。可能?

对于我来说,为这段代码编写单元测试(即遍历订单集合,根据业务规则和子对象聚合信息等)是很有意义的。 要做到这一点,我希望我的代码看起来约。像这样

foreach (IOrder in Orders) 
    foreach (IOrderLine in IOrder.Orderlines) 
    ... 

    return ... 

然后测试返回值。

但是这段代码并不是在报表视图中使用的SQL ......当然...... 所以我在想,我可以在数据库中插入一个.NET程序集。 这里的问题当然是性能......我不想在C#中循环所有这些对象......太慢了。

因此,自然,Linq/Lambda/Expression树似乎是我的答案。 正如我们所知道的那样,当您将Linq转换为SQL时,会构建表达式树,然后根据它们生成适当的SQL。因此,我可以使用lambda表达式在Linq中将我的代码写入到对象中,并在样本集合(将表达式编译为.net)上单元测试此代码,并在DB存储过程中重复使用与Linq to SQL相同的代码,所以在SQL Server内部它会为我生成适当的SQL(就像Linq to SQL已经做到的那样)...

然后,我可以从C#和高性能存储中获得单元测试和编写域逻辑代码的好处报告程序。

可能吗? 我可以在SQL Server CLR存储过程中使用Linq/Lambda吗?任何人做过或知道如何使它工作? 我疯了吗?你知道更好的方法吗?

感谢

附:我想现在我想出了这应该如何正确完成。据Udi Dahan说,如果我理解他是对的。数据库应该是非规范化的,并且所有计算的字段应该位于表格中的对象上。 当子对象发生某些事情时(OrderLine添加),我的Customer对象应该接收一个事件并重新计算智能值(缓存并保存)。

然后报告直行向前,没有逻辑和工作速度快...

回答

1

不,你不能在SQL CRL特效使用LINQ/LAMBDA - 这是基于不同版本的.NET和不支持这些命名空间。

1

所以,我可以写我在LINQ的代码 对象,使用lambda表达式, 单元测试此代码上样品 集合(具有表达 编译到.NET),并且重复使用相同的 代码的LINQ在SQL存储过程中存储 过程,因此SQL Server内部的 它会为我生成适当的SQL (因为Linq to SQL已经这样做)...

这个计划一直很好,直到你建议从存储过程中调用CLR代码。从数据库进程本身运行CLR代码会在版本控制,配置和数据库稳定性方面产生很多问题......如果这样做的话,问题太多。

你的动机是有使用存储过程的好处,一般速度更快。如果这些存储过程依次运行CLR代码,它们不会比在本地过程中运行的CLR代码更快。

使用LINQ生成的表达式在技术上会比存储的特效消耗更多的CPU周期。这是因为每次运行查询时,数据库引擎都必须重新生成执行计划。通常情况下,您的数据库服务器位于单独的计算机上,但不受CPU限制(它将受限于磁盘或网络容量),因此这不是真正的性能问题。这可能是因为如果你在一台机器上运行数据库服务器而不是其他所有的东西,但是不要试图用一些如此复杂的东西来解决这个问题,直到它成为一个真正的问题。

如果您想减少生成报告的开销,Udi的建议可能是适当的。首先要考虑两个重要的副作用。首先,是否可以承担增加预生成报告字段的操作的性能开销?更大的问题是它将报告逻辑与运行目标系统的代码结合在一起。这会阻止您在不更新业务代码的情况下更新报告代码,并假设报告的代码在投入生产后立即运行。