List(Of <custom class =“”>)似乎重置自己

时间:2015-09-25 00:47:39

标签: asp.net asp.net-mvc vb.net

代码:

我有一个类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

1 个答案:

答案 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