Linq to XML:查询返回相同结果3次而不是3次结果

时间:2011-10-30 13:23:07

标签: winforms linq-to-xml

我的XML文件中有3个存款,但查询只返回第一个存款3 thime。我已经在Customer类和XML文件中进行了调整。这是一个.Net 4窗体表单应用程序。当用户点击“存款”按钮时,存款会显示在表格上。

调用Customer Class的用户Inerface表单方法:

    private void btnDeposits_Click(object sender, EventArgs e)
    {
        if (customerId == "0")
        {
            MessageBox.Show("Please first select a customer", "Error");
            return;
        }

        BL_Customer oCustomer = new BL_Customer();

        try
        {
            //Call method to pull data from XML
            oCustomer.getDeposits(customerId);
        }
        catch (Exception ex)
        {
            tssErrors.Text = ex.Message;
        }

        //Set datagridview datasource and format the view Headers & Cells
        dgvDeposits.DataSource = oCustomer.Deposits;
        dgvDeposits.Columns[0].HeaderText = "Deposit ID";
        dgvDeposits.Columns[1].HeaderText = "Amount";
        dgvDeposits.Columns[2].HeaderText = "Date of Deposit"; 
        dgvDeposits.Columns[0].HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter;
        dgvDeposits.Columns[1].HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter;
        dgvDeposits.Columns[2].HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter;
        dgvDeposits.Columns[0].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft;
        dgvDeposits.Columns[1].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
        dgvDeposits.Columns[2].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft;
        dgvDeposits.Columns[1].DefaultCellStyle.Format = "c2";
        dgvDeposits.Columns[0].Width = 50;
        dgvDeposits.Columns[1].Width = 60;
        dgvDeposits.Columns[2].Width = 80;
    }

CUSTOMER类

   public BL_Customer()
    {
        oDeposits = new List<BL_Deposit>();
    }

    public List<BL_Deposit> addDeposits(BL_Deposit oDeposit)
    {
        oDeposits.Add(oDeposit);
        return oDeposits;
    }

   public double  getDeposits(string customerId)
    {
        double sumDep = 0;
        //Returns list of deposits for selected customer
        var doc = XDocument.Load("Portfolio.xml");
        var Deposits = from account in doc.Descendants("account")
                       from deposit in account.Elements("deposits")
                       where (string)account.Element("acct").Attribute("custid").Value == customerId
                       select new
                       {
                           Depid = (string)deposit.Attribute("depid").Value,
                           Amount = (string)deposit.Attribute("depamount").Value,
                           Date = (string)deposit.Attribute("depdate").Value
                       };

                        //Loop through deposits and add a deposit object
                        BL_Deposit oDeposit = new BL_Deposit();
                        for (int i = 0; i < 3; i++)
                        {
                            oDeposit.DepAmt = Convert.ToDouble(Deposits.ElementAt(i).Amount);
                            oDeposit.DepDate = Convert.ToDateTime(Deposits.ElementAt(i).Date);
                            oDeposit.DepositId = Convert.ToInt32(Deposits.ElementAt(i).Depid);
                            addDeposits(oDeposit);
                            sumDep += oDeposit.DepAmt;
                        }
                        return sumDep;
        }

XML文件

<?xml version="1.0" encoding="utf-8" ?>
<portfolio>
  <account>
    <acct custid="1" fname="Tommy" lname="Hawk" ssn="928-329-1929" dob="4/6/1988"></acct>
    <deposits depid="1000" depdate="1/2/2011" depamount="1350.53"></deposits>
    <deposits depid="1003" depdate="2/3/2011" depamount="1377.81"></deposits>
    <deposits depid="1008" depdate="3/14/2011" depamount="84.00"></deposits>
    <withdrawals wdid="2001" wddate="1/31/2011" wdamount="80.00"></withdrawals>
    <withdrawals wdid="2005" wddate="4/8/2011" wdamount="80.00"></withdrawals>
    <withdrawals wdid="2007" wddate="6/1/2011" wdamount="2600.00"></withdrawals>
  </account>
  <account>
    <acct custid="2" fname="I. P." lname="Nightly" ssn="457-23-4871" dob="6/1/1945"></acct>
    <deposits depid="1004" depdate="2/8/2011" depamount="741.22"></deposits>
    <deposits depid="1005" depdate="2/9/2011" depamount="47.00"></deposits>
    <deposits depid="1009" depdate="3/14/2011" depamount="89.99"></deposits>
    <withdrawals wdid="2003" wddate="3/1/2011" wdamount="55.00"></withdrawals>
    <withdrawals wdid="2004" wddate="3/3/2011" wdamount="28.00"></withdrawals>
    <withdrawals wdid="2006" wddate="4/8/2011" wdamount="450.00"></withdrawals>
  </account>
  <account>
    <acct custid="3" fname="Mary" lname="Echmass" ssn="192-01-2933" dob="8/10/1973"></acct>
    <deposits depid="1002" depdate="1/15/2011" depamount="841.77"></deposits>
    <deposits depid="1006" depdate="2/14/2011" depamount="2170.00"></deposits>
    <deposits depid="1007" depdate="3/10/2011" depamount="21.01"></deposits>
    <withdrawals wdid="2002" wddate="1/16/2011" wdamount="700.00"></withdrawals>
    <withdrawals wdid="2008" wddate="6/3/2011" wdamount="24.00"></withdrawals>
    <withdrawals wdid="2009" wddate="6/30/2100" wdamount="38.46"></withdrawals>
  </account>  
</portfolio>

1 个答案:

答案 0 :(得分:1)

您使用BL_Deposit oDeposit = new BL_Deposit();创建单个对象,然后在循环中更改同一对象的属性。将创建对象的代码移动到循环中,然后我认为你应该得到你想要的东西。

当然,您可以直接在查询中创建对象,避免使用匿名对象。

[编辑] 以下是如何使用LINQ直接创建List:

List<BL_Deposit> deposits =
  (from account in doc.Descendants("account")
from deposit in account.Elements("deposits")
where (string)account.Element("acct").Attribute("custid").Value == customerId
select new BL_Deposit() 
{
    DepositId = (int)deposit.Attribute("depid"),
    DepAmt = (double)deposit.Attribute("depamount"),
    DepDate = Convert.ToDateTime(deposit.Attribute("depdate").Value)
}).ToList();

然后你也可以用例如和sumDep = deposits.Sum(d => d.DepAmt);