【发布时间】:2019-03-21 19:25:43
【问题描述】:
如果这应该是在代码审查而不是在这里,首先道歉。我想这里是因为我只显示伪代码。
我有一个从数据库加载的对象,该对象又具有从数据库中获取的延迟加载属性。
Public Class Item
Public Sub New(pRow as Datarow)
Me.ID = CLng(pRow.Item(“ID”))
‘ Fill other properties from datarow
End Sub
Private _Tags as List(Of Tag)
Public Readonly Property ID as Long = 0
Public Readonly Property Tags as List(Of Tag)
Get
If _Tags Is Nothing Then _Tags = LoadTagsFromDB(Me.ID)
End Get
End Property
End Class
现在这很棒,它允许我加载一个对象的实例。使用它的属性,如果我需要标签,我可以将它们抓取到数据库一次。
当我有 Ienumerable(Of Item) 时会出现此问题
在某些情况下,我的收藏规模可能远远超过 50,000+
这显然意味着当我抓取集合然后对其进行迭代时,我在访问每个项目实例上的 Tags 属性时过度敲击数据库。
我已经按照以下方式重新编写了代码。
Public Class Item
Public Sub New(pRow as Datarow)
Me.ID = CLng(pRow.Item(“ID”))
‘ Fill other properties from datarow
End Sub
Public Readonly Property ID as Long = 0
Public Readonly Property Tags as List(Of Tags) = Nothing
Public Sub SetTags(pDictionary as Dictionary(Of Long, List(Of Tag))
If pDictionary.ContainsKey(Me.ID) Then
_Tags = pDictionary.Item(Me.ID)
Else
_Tags = New List(Of Tag)
End If
End Sub
End Class
这让我可以做以下事情。
‘ Grab the unique ids from the collection
Dims ids = ListOfItems.Select(function(x) x.ID).Distinct
‘ One query, giant result set.
Dim d = SQLToGetAllTagsWithIDs(IDs)
For Each o As Item in ListOfItems
o.SetTags(d)
Next
这是完美的,几乎无限快,但是当使用 Item 的单个实例或不调用 .SetTags 时,.Tags 属性什么都不是
我已经混合并匹配了这两种场景,因此如果不调用它,它会在第一个实例中通过机制回退并获取它,但这让我回到第一个场景,其他开发人员只会允许没有意识到 SetTag 存在或其目的的惰性机制。
我想我的问题是,是否有一些我不知道的模型或首选方式来做我想做的事情,从而实现两全其美?我很难用谷歌搜索这个问题,因为它很难解释。
希望这是有道理的,希望有一个解决方案,如果没有,我想我会坚持我所拥有的。
【问题讨论】:
-
表示需要
Item的集合。但是,是否强制消费者可以直接创建Item?如果没有,请考虑仅公开ItemCollection类型。 ItemCollection 将处理新的Item对象创建,如果需要,它的Tags属性将调用ItemCollection上的方法来加载Tags。ItemCollection将保持调用计数,当达到阈值时,将填充所有未填充的Item对象。这将是一项设置工作,因为ItemCollection需要实现IList(of Item),但它可以防止大多数滥用情况。 -
不幸的是,还需要有一个项目实例。事实上,在大多数情况下,它是一个,但在几页上,我向用户展示了完整的项目列表。
标签: .net vb.net lazy-loading ienumerable