【问题标题】:populate object graph from database从数据库填充对象图
【发布时间】:2016-03-15 02:40:05
【问题描述】:

我想知道填充具有子对象集合的对象的最佳方法,并且每个子对象又可能具有来自数据库的对象集合,而无需多次调用数据库以获取每个对象的子对象.基本上采用分层格式,例如客户有订单,每个订单都有订单项目。最好以 xml 格式(SQL server 2005)检索数据,还是通过将相关表连接在一起来检索数据集,然后将该数据映射到对象?提前感谢您的帮助。

【问题讨论】:

标签: c# sql-server-2005


【解决方案1】:

还有很多变数:

  1. 子对象是否属于同一类型?如果是这样,您可以同时选择它们,然后在对象映射层中设置父/子关系。
  2. 子对象可以有自己的子对象吗?如果嵌套是无限的,那么除非您获取所有数据,否则您无法同时获取所有数据。

您当然可以对所有客户->订单->订单商品进行连接并在代码中分解所有内容,但这似乎会在重复的父行中产生大量开销,并且在处理过程中需要大量工作这么大的烂摊子。

尝试避免多次调用可能是一种未成熟的优化。您是否因对数据库进行过多调用而遇到性能问题?

编辑:根据您的 cmets,您应该能够在每个层次结构级别执行一次查询:

Select * from orders 
where orders.customerid = my_customer_id

--做一些orm映射并列出子对象ID--

Select * from child_order_object 
where child_order_object_id in (list of child object ids)

--做更多的 ORM 映射并将子对象链接到以前的父对象--

...

--重复更多关卡--

每个关系级别应该只能有一个查询,而不是通过 id 只获取一个对象的查询量激增。

【讨论】:

  • 不,子对象的类型不同。是的,当我需要一次性检索大量数据时,它会导致性能问题,而且我认为这不是有效的方法。假设客户有 30 个订单,并假设每个订单除了订单项目之外还有另一个子对象集合,这将是 60 次调用来检索客户的所有订单(每个订单两个数据库调用),完全填充了子对象。这只是这里用来解释问题的一个例子。
  • 我们没有在我们的项目中使用任何 ORM 工具,因此目前无法选择将所有现有的数据访问代码转换为使用该工具。所以我认为要么我需要检索一个连接的数据集,然后解析它以构造对象的层次结构,要么从数据库中获取一个 xml。无论如何感谢您的信息。
【解决方案2】:

您可以查看专为此类场景设计的ORMs,例如NHibernateEntity Framework

【讨论】:

  • ORM 仍然会多次调用数据库,不是吗?
  • @Tiberiu Ana - 只能代表 NHibernate,但您可以通过使用 Eager fetching 或在 HQL 语法中指定连接来避免多次数据库调用。
  • 我想看看证明。除非它使用递归查询,或者它一次读取表中的每个对象,否则它将不得不多次访问数据库。我认为 NHibernate 支持的很多数据库都不会支持递归查询。
  • (是的,一个 ORM 将填充对象图,并且可能在一次调用 ORM 时,但 ORM 将多次访问数据库来执行此操作。)
【解决方案3】:

MS SQL 2005 支持通用表表达式,可用于此目的。基本上它们允许您进行递归查询。在 CTE / MS SQL 上做一个关键字搜索,你会发现很多这样的东西:Apply a recursive CTE on grouped table rows (SQL server 2005)

【讨论】:

    【解决方案4】:

    这个问题很老,但新的答案(如果您使用实体框架)是在对象查询上使用 Include 方法。这将急切地加载指定的所有导航属性。

    https://msdn.microsoft.com/en-us/library/bb738708(v=vs.100).aspx

    【讨论】:

      猜你喜欢
      • 2014-02-07
      • 2013-03-27
      • 1970-01-01
      • 2013-10-04
      • 1970-01-01
      • 2010-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多