我正在为报告模型(SQL Server Reporting Services)创建数据源。 这些报告需要大量的连接和计算(比方说,计算财务参数,比如花在这上面的金额,金额A和金额B)......所有这些都涉及子对象。
为这段代码编写单元测试对我来说很有意义(即通过订单集合,根据业务规则和子对象聚合信息等) 要做到这一点,我希望我的代码看起来很近。像这样
foreach (IOrder in Orders)
foreach (IOrderLine in IOrder.Orderlines)
...
return ...
然后测试返回值。
但是这段代码不是将在报告视图中使用的SQL ......当然...... 所以我在想,我可以在数据库中插入一个.NET程序集。 这里的问题当然是性能......我不想在C#中循环所有这些对象......太慢了。
所以,当然,Linq / Lambda / Expression树似乎是我的答案。 我们知道,当您使用Linq to SQL时,会构建表达式树,然后根据它们生成适当的SQL。
所以,我可以使用lambda表达式在Linq中编写我的代码,在样本集合上单元测试此代码(将表达式编译为.net),并在DB存储过程中重用与Linq to SQL相同的代码,所以在SQL Server内部它会为我生成适当的SQL(正如Linq to SQL已经做的那样)......
然后,我可以从单元测试中获益,并在C#中编写域逻辑代码,并为报告提供高性能的存储过程。
可能? 我可以在SQL Server CLR存储过程中使用Linq / Lambda吗?任何人都做过或知道如何使其工作? 我疯了吗?你知道更好的方法吗?
由于
P.S。我想我现在已经弄清楚应该如何正确地完成。根据Udi Dahan的说法,如果我理解他的话。数据库应该非规范化,并且所有计算的字段应该在表中的对象上。 当子对象上发生了某些事情(添加了OrderLine)时,我的Customer对象应该收到一个事件并重新计算智能值(缓存它并保持不变)。
然后报告直截了当,没有逻辑,工作得很快......
答案 0 :(得分:1)
不,您不能在SQL CRL过程中使用LINQ / Lambda - 它基于不同版本的.NET,并且不支持这些名称空间。
答案 1 :(得分:1)
所以,我可以在Linq中编写我的代码 对象,使用lambda表达式, 单元测试此代码的样本 集合(有表达式 编译成.net),并重用相同的 代码作为Linq to SQL存储在DB中 程序,使SQL Server内部 它会为我生成适当的SQL (正如Linq to SQL已经做的那样)......
这个计划没问题,直到你建议从你的存储过程中调用CLR代码。从数据库进程本身运行CLR代码会在版本控制,配置和数据库稳定性方面产生很多问题......如果你这样做会产生很多问题。
你的动机是使用存储过程的好处,一般来说速度更快。如果那些存储过程依次运行CLR代码,它们将不会比在本地进程中运行的CLR代码更快。
使用LINQ生成的表达式在技术上比存储过程消耗更多的CPU周期。这是因为每次运行查询时,数据库引擎都必须重新生成执行计划。通常,您的数据库服务器位于单独的计算机上,但不受CPU限制(它将受磁盘或网络容量限制),因此这不是真正的性能问题。可能是因为你在同一台机器上运行数据库服务器而不是其他所有东西,但是不要试图用一些如此复杂的东西来修复它,直到它成为一个真正的问题。
如果您想减少生成报告的开销,那么Udi的建议可能是合适的。首先要考虑两个重要的副作用。首先,是否能够增加预生成报告字段的操作的性能开销?更大的问题是它将您的报告逻辑与运行目标系统的代码耦合在一起。这会阻止您在不更新业务代码的情况下更新报告代码,并且只要报告的代码投入生产,就会假定报告代码正在运行。