【问题标题】:Efficient way to load lists of objects from database to instantiate a single object从数据库加载对象列表以实例化单个对象的有效方法
【发布时间】:2012-09-14 14:06:42
【问题描述】:

我的情况

我有一个包含一些列表的 c# 对象。例如,这些列表之一是标签列表,它是 c#“SystemTag”对象的列表。 我想以最有效的方式实例化这个对象

在我的数据库结构中,我有以下表格:

  • dbObject - 包含有关我的 c# 对象的一些基本信息的表
  • dbTags - 所有可用选项卡的列表
  • dbTagConnections - 一个包含 2 个字段的列表:TagID 和 ObjectID(以确保一个对象可以有多个标签)

(我还有其他几种类似的数据)

我现在就是这样做的……

  1. 使用 ID 从数据库中检索我的对象
  2. 将 DB 对象发送到“对象工厂”模式,然后意识到我们必须获取标签(和其他列表)。然后它使用我们的 C# 对象的 ID 向 DAL 层发送调用
  3. DAL 层从 DB 中检索数据
  4. 这些数据被发送到转换为标签的“TagFactory”模式
  5. 我们回到了对象工厂

这真的很低效,我们对数据库有很多调用。这尤其会带来问题,因为我有 4 种以上类型的列表。

我尝试了什么?

我不太擅长 SQL,但我尝试了以下查询:

SELECT * FROM dbObject p
LEFT JOIN dbTagConnection c on p.Id=  c.PointId
LEFT JOIN dbTags t on c.TagId = t.dbTagId
WHERE ....

但是,这会检索与标记连接一样多的对象 - 所以我不认为连接是实现此目的的好方法。

其他信息...

  • 使用 .NET Framework 4.0
  • 使用 LINQ to SQL(BLL 和 DAL 层以及 BLL 中的工厂模式从 DAL 对象转换)

...

那么 - 我如何尽可能高效地解决这个问题? :-) 谢谢!

【问题讨论】:

  • 我认为您的 WHERE 子句包含您要检索的对象的 ID?
  • 是的,这是真的。但是,我还需要获取我的对象列表 - 在这些情况下当然不是 :-)
  • 有很多注意事项。 SO thread 有一些很棒的数据访问讨论。具体来说,如果您正在寻找速度(在您对效率的呼吁中),我会考虑实体框架。以我的经验,如果您有能力提前投入时间来正确连接所有内容,那么 linq to entity 比 linq to sql 快得多。

标签: asp.net sql performance linq-to-sql


【解决方案1】:

乍一看,我不认为您当前的工作方式“效率低下”(提供的信息)。我会替换代码:

SELECT * FROM dbObject p
LEFT JOIN dbTagConnection c on p.Id=  c.PointId
LEFT JOIN dbTags t on c.TagId = t.dbTagId
WHERE ...

通过两次调用 DALs 方法,第一次检索对象主要数据 (1),然后一次仅获取相关标签的数据 (2),以便您的工厂可以填充对象的标签列表:

(1)

SELECT * FROM dbObject WHERE Id=@objectId

(2)

SELECT t.* FROM dbTags t
INNER JOIN dbTag Connection c ON c.TagId = t.dbTagId
INNER JOIN dbObject p ON p.Id = c.PointId
WHERE p.Id=@objectId

如果您有很多对象并且数据量只有少数(这意味着您不会管理大量数据),那么我会寻找基于 ORM 的解决方案,例如 Entity Framework

我(仍然)觉得在 DAO 中编写 SQL 查询来控制所有发送到数据库服务器的查询很舒服,但最后是因为在我们的情况下是需要的。我认为必须查询数据库以恢复,首先,对象数据 (SELECT * FROM dbObject WHERE ID=@myId) 并填充对象实例,然后再次查询数据库以恢复您可能需要的所有卫星数据,我认为没有任何不便(标签在你的情况下)。

您的方案更加简洁,以便我们可以针对您的特定方案提供有价值的建议。无论如何,希望这对你有用。

【讨论】:

    【解决方案2】:

    据我推测,您的数据库已经存在并且您对 SQL 已经足够熟悉了。

    您可能想要使用微型 ORM,例如 petapoco

    要使用它,您必须编写与数据库中的表匹配的类(有 T4 生成器可以使用 Visual Studio 2010 自动执行此操作),然后您可以编写包装器来创建更丰富的业务对象(您可以使用ValueInjecter 来做,这是我用过的最简单的),或者你可以照原样使用它们。

    Petapoco 处理插入/更新操作,并自动检索生成的 ID。

    因为 Petapoco handles multiple relationships 也是,它似乎符合您的要求。

    【讨论】:

      【解决方案3】:

      您是否考虑过使用实体框架?然后,您将与您的数据库进行交互,就像您与应用程序中的任何其他类型的类进行交互一样。

      设置起来非常简单,您可以在实体设计器中创建数据库表之间的关系 - 这将为您提供调用相关对象所需的所有外键。如果您在数据库中设置了所有键,那么实体设计器将使用这些键 - 创建所有对象就像选择“从数据库创建模型”一样简单,当您对数据库进行更改时,您只需右键单击您的设计器并选择“从数据库更新模型”

      该框架会为您处理所有 SQL - 因此您无需担心;在大多数情况下..

      一个很好的起点是herehere

      完成所有设置后,您就可以使用 LINQ 轻松查询数据库。

      您会发现这比沿表适配器路由更有效(假设您目前正在这样做?)

      抱歉,如果我遗漏了什么,而您已经在使用它.. :)

      【讨论】:

        【解决方案4】:

        我们使用了返回多个结果集的存储过程,在以前使用 Java/MSSQL 服务器/Plain JDBC 的项目中的情况类似。

        存储过程取要检索的对象对应的ID,返回构建主对象的行,后跟与主对象的每个一对多关系的多条记录。这使我们能够在单个数据库交互中完整地构建对象。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-19
          • 2017-07-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多