【问题标题】:VB.NET - PetaPoco\NPoco - Fetch data from table with dynamic and static columns - Performance issueVB.NET - PetaPoco\NPoco - 从具有动态和静态列的表中获取数据 - 性能问题
【发布时间】:2015-09-23 11:45:06
【问题描述】:

我有一个具体的情况,我还没有找到解决办法。

我有几个具有相同结构的数据库,其中有一个表(比如说Users),它具有已知的列,例如:UserIDUserNameUserMail 等... 在同一张表中,我有动态自定义列,我只能在运行时知道这些列,例如:customField54customField75customField82 等...

我有一个屏幕,我必须在其中显示用户列表,并且有数千条记录(必须显示 ALL 用户 - 毫无疑问)。

数据库 A 中的 Users 表列如下所示:

| UserID | UserName | UserMail | customField54 | customField55 |

例如,假设我有另一个数据库 B,那里的表用户如下所示:

| UserID | UserName | UserMail | customField109 | customField211 | customField235 | customField302 |

我有一个代码,每次都连接到另一个数据库。所以我有一个代码 -> 多个数据库,而每个数据库的区别是Users表的自定义字段。

如果我使用 DataTable,我可以查询:

    SELECT * FROM Users

然后,我可以动态检索自定义字段值,如下所示:

Dim customFieldsIDs() As Integer = GetCustomFieldsIDs()
Dim dt As DataTable = GetUserListData() // All users data in a DataTable

For Each dr In dt.Rows
    Response.Write(dr.Item("UserID"))
    Response.Write(dr.Item("UserName"))
    Response.Write(dr.Item("UserMail"))

    For Each cfID in customFieldsIDs
         Response.Write(dr.Item("customField" & cfID))
    Next 
Next

我的目的不是使用 DataTables。我想使用强类型对象。我无法使用内部的 customFields 创建用户 POCO,因为对于每个数据库,Users 表都有不同的 customFields 列,因此我无法创建具有强类型变量的对象。

然后,我决定创建一个包含已知列的用户类,以及一个包含 customFields 的字典。

在VB.NET中,我创建了一个Users类,如下所示:

Public Class User
    Public Property UserID As Integer
    Public Property UserName As Integer
    Public Property UserMail As Integer

    Public Property customFieldsDictionary As Dictionary(Of Integer, String)
End Class

该类具有静态值:UserIDUserName 等... 此外,它还有一个包含 customFieldIDs 及其值的字典,因此我可以在单个操作中检索值(在 O(1) 复杂度中)


我使用 MicroORM PetaPoco\NPoco 来填充这些值。 ORM 允许我获取用户数据,而无需我自己迭代数据,方法是调用:

Dim userList As List(Of User) = db.Fetch(Of User)("SELECT * FROM Users")

但是customFields 字典没有填充。 为了填充,我必须迭代 userList 并为每个用户检索 customFields 数据。 这是获取数据的一种非常昂贵的方式,并且会导致性能非常差。

我想知道是否有一种方法可以通过单个命令使用 PetaPoco\NPoco 将数据提取到 User 类中,并设法为每个用户填充已知值和自定义字段字典,而无需遍历整个集合。

我希望它被理解。这对我来说真的很难解释,也是一个很难找到解决方案的问题。

【问题讨论】:

  • NPoco V3 会有这样的东西。结帐 Test28()。 github.com/schotime/NPoco/blob/dev3.0/src/NPoco.Tests/NewMapper/…希望这个周末会有一个 Alpha 版
  • 您能解释一下 Test28 函数中的 SQL 命令应该如何工作吗?它看起来像这样:“选择 3 Id, 'Name' Name, null, 'dyn' Dynamic__Value1, 'dict' Dict__Value2”。这对我来说有点奇怪。 'dict' Dict__Value2 代表什么?请查看我在原始帖子中显示的数据库表。您能否向我展示一个如何使用我的数据库实现 Test28 功能的示例?

标签: sql-server vb.net petapoco micro-orm npoco


【解决方案1】:

您可以尝试将所有内容提取到字典中,然后您可以将特定的键/值映射到您的用户对象属性。

编辑:

我不再使用 VB.NET,但我会尝试解释一下。

创建与此类似的索引器: http://www.java2s.com/Tutorial/VB/0120__Class-Module/DefineIndexerforyourownclass.htm

在索引器中,您可以执行以下操作:

if (index == "FirsName") then
  me.FirstName = value
end if

....

if (index.startWith("customField") then
  var indexValue = int.Parse(index.Replace("customField",""))
  me.customFieldsDictionary[indexValue]  = value
end if

NPoco 支持将数据实体化为字典:

var users = db.Fetch<Dictionary<string, object>>("select * from users");

您应该能够将您的类传递给 NPoco 并强制它为字典使用 Fetch 重载。

我以前用过这种方法,但暂时找不到源。

【讨论】:

  • 确实如此,您可以查看我帖子中的第一个示例,看看我就是这样做的。但随后它将迫使我遍历每个用户并复制所需的属性,从而导致性能下降。我想以正确的格式获取 Fetch 命令中的全部数据
  • 对不起,我忽略了。如何在 User 对象上实现 IDictionary 接口并在索引器中设置属性值?
  • 我不太确定我是否理解您的建议。你介意举个例子来说明你的意思吗?
  • 我不是 VB.NET 专家,但我会尽力解释。
猜你喜欢
  • 2014-11-19
  • 2012-12-20
  • 2015-08-27
  • 2021-09-01
  • 2013-08-22
  • 2021-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多