2009-05-29 49 views
0

我正在维护一个用C#编写的内部ORM,它目前没有任何热切加载机制。为了提高性能,我们决定需要加载,所以我们需要编写自己的代码来支持它。 (我的同事和我没有任何ORM工具的经验,而且,由于一些遗留原因,我们不允许使用流行的工具,如LinqtoSQL,Entity Framework或Nhibernate。)需要关于编写我自己的急切加载算法的建议

我的问题是,这是生成急切加载SQL语句的最佳实践吗?我已经想过这个问题,并提出了两种方法 -

假设4桌一个典型的例子 - 一个CustomerCategory有许多客户 一个客户有很多订单 一个订单有许多的OrderDetail

,并假设我想要从所有4个表中急切加载数据,并且我的条件是 - 其中Order.OrderDate'2008-05-05'和'2008-12-31'之间

方法1 - 我生成一个sql以获取来自所有4个表的数据,全部使用内部连接,以便每个表的主键的每个唯一组合都有一行。我会将我的Where条件应用于此SQL。

方法2 - 我生成一个SQL来首先获取订单数据,并将此Where条件应用于此SQL,因为Order.OrderDate来自Order表。 然后,根据我的查询结果,我将知道所需的所有订单ID值,因此我将使用它们来检索订单明细数据。我也会知道我需要的所有唯一的Customer ID值,所以我也将使用这些值来从客户表中检索数据,最后我会为CustomerCategory执行相同的操作。这个方法总共需要4个SQL语句。

我可以看到第一种方法更有效率,但是我的一位同事指出第二种方法尽管使用4个SQL语句,但它更容易编写和维护,我同意这一点。

对此的任何想法将不胜感激。 谢谢!

回答

0

首先,你的域模型是大量错误的。我个人无法证明中收集Customer对象是有道理的,因为从性能的角度来看,它只是没有意义:大多数时候你需要一个客户(加上它的组),而一组客户将需要一次蓝色的月亮,但它会一直在那里,造成各种问题。 Customer同样适用于许多Order

现在,你的问题。通常认为数据库往返次数应尽可能少,即使以检索更多数据为代价,也不必要。也就是说,加入两个大表(长&宽)同时从两个关联表中选择数据可能是一个性能杀手,所以要小心。

我建议你看看它是如何在NHibernate中完成的。它允许您为每个关联指定获取策略(连接,选择),无论是一对一关联还是一对多关联。

如果您使用的Microsoft SQL Server 2005或更高版本,可以使用MARS充塞几个select s转换一批,然后滋润只发出一个SQL命令对象的整个图形。

+0

感谢您的帮助。 我承认我们的模型确实有问题。 我们会研究它,并会根据您的建议看看nhibernate 。 – janem 2009-06-01 15:42:28