2

我正在为报告模型(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 to Objects 中编写我的代码,在示例集合上对这段代码进行单元测试(将表达式编译为 .net),并在 DB 存储过程中重用与 Linq to SQL 相同的代码,以便在内部SQL Server 它会为我生成正确的 SQL(就像 Linq to SQL 已经做的那样)......

然后我可以从单元测试和用 C# 编写域逻辑代码以及用于报告的高性能存储过程中获益。

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

谢谢

PS我想现在我想出了应该如何正确地做到这一点。根据 Udi Dahan 的说法,如果我理解他的话。数据库应该是非规范化的,所有计算的字段都应该在表中的对象上。当子对象(添加了 OrderLine)发生某些事情时,我的 Customer 对象应该接收一个事件并重新计算智能值(缓存它并保持)。

然后报告直截了当,没有逻辑并且工作快速......

4

2 回答 2

1

不,您不能在 SQL CRL Procs 中使用 LINQ/Lambda - 它基于不同版本的 .NET,并且不支持这些命名空间。

于 2008-12-02T21:14:02.320 回答
1

因此,我可以使用 lambda 表达式在 Linq to Objects 中编写我的代码,在示例集合上对这段代码进行单元测试(将表达式编译为 .net),并在 DB 存储过程中重用与 Linq to SQL 相同的代码,以便在内部SQL Server 它会为我生成正确的 SQL(就像 Linq to SQL 已经做的那样)......

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

您的动机是受益于使用存储过程,这通常更快。如果这些存储过程依次运行 CLR 代码,它们不会比在本地进程中运行的 CLR 代码快。

从技术上讲,使用 LINQ 生成的表达式比存储的过程消耗更多的 CPU 周期。这是因为数据库引擎必须在每次运行查询时重新生成执行计划。通常,您的数据库服务器位于单独的计算机上,尽管它不受 CPU 限制(它将受到磁盘或网络容量的限制),因此这不是真正的性能问题。如果您在与其他所有设备相同的机器上运行数据库服务器,则可能是这样,但不要尝试用如此复杂的东西来解决这个问题,直到它成为真正的问题。

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

于 2008-12-02T22:50:30.020 回答