我有一个类Pricing.vb
,它在新方法中接受IEnumerable(Of tblAccount)
,其中tblAccount
是一个实体框架类,其中添加了一个添加了非映射属性的部分类。
Pricing.vb:
Public Property accounts As IEnumerable(Of tblAccount)
Public Sub New(ByVal accts As IEnumerable(Of tblAccount))
Me.accounts = accts
End Sub
tblAccount.vb:
Partial Public Class tblAccount
<NotMapped>
Public Property irr As Double
End Class
然后Pricing.vb
类有一个方法CalcBalance
:
Public Sub CalcBalance(reqPrice As Double)
Dim acctsByIRR As List(Of Long)
Dim i As Long = 0
Me.FillCashFlows(reqPrice)
Me.FillMetrics()
acctsByIRR = Me.accounts.OrderBy(Function(t) t.irr).Select(Function(t) t.acct_id).ToList()
'do ... while that removes accounts 1 by 1 by lowest ray until it is above min
Do While Me.netIRR < Me.minimumIRR
Me.accounts = Me.accounts.Where(Function(t) t.acct_id <> acctsByIRR(i))
i = i + 1
If Me.accounts.Count = 0 Then Exit Sub
Me.FillCashFlows(reqPrice)
Me.FillMetrics()
Loop
End Sub
基本上,CalcBalance()
方法旨在以最低IRR的顺序从其属性tblAccount
逐个删除Me.Accounts
个对象,直到剩余帐户的IRR( Me.netIRR
)符合最低标准(Me.minimumIRR
)。 Me.netIRR
属性由方法FillCashFlows()
和FillMetrics()
计算。
我看到的问题是Me.accounts
每次执行while循环时都会自行重置。因此,如果我tblAccounts
{1}到1 {1},并且让我们说最低IRR的顺序是1,2,3,4和5,那么第一次方法循环它将从acct_id
正确删除acct_id=1
。但是,下次循环时,Me.accounts
将重新出现在acct_id=1
中,它将删除Me.accounts
。它将继续这个奇怪的过程,直到它达到超出范围异常的索引。
acct_id=2
在每个循环之后IEnumerable(Of tblAccount)
所看到的内容:第一次循环后:
acct_id
第二次循环后:
2
3
4
5
第3次循环后:
1
3
4
5
第4次循环后:
1
2
4
5
第5次循环后:
1
2
3
5
第一次循环后:
1
2
3
4
第二次循环后:
2
3
4
5
第3次循环后:
3
4
5
第4次循环后:
4
5
第5次循环后:
5
答案 0 :(得分:2)
这是因为您使用的是IEnumerable<T>
而不是List<T>
。 LINQ查询是延迟加载的,因此您的accounts
属性存储查询信息(如何获取结果)而不是帐户列表。在Do/While
的每次迭代中,您只需更改定义,稍后就会反复调用初始数据源。
每当您分配到ToList
时,请务必致电accounts
:
Public Sub New(ByVal accts As IEnumerable(Of tblAccount))
Me.accounts = accts.ToList()
End Sub
和
Public Sub CalcBalance(reqPrice As Double)
Dim acctsByIRR As List(Of Long)
Dim i As Long = 0
Me.FillCashFlows(reqPrice)
Me.FillMetrics()
acctsByIRR = Me.accounts.OrderBy(Function(t) t.irr).Select(Function(t) t.acct_id).ToList()
'do ... while that removes accounts 1 by 1 by lowest ray until it is above min
Do While Me.netIRR < Me.minimumIRR
Me.accounts = Me.accounts.Where(Function(t) t.acct_id <> acctsByIRR(i)).ToList()
i = i + 1
If Me.accounts.Count = 0 Then Exit Sub
Me.FillCashFlows(reqPrice)
Me.FillMetrics()
Loop
End Sub