Linq to XML: запрос возвращает один и тот же результат 3 раза вместо 3 результатов

#winforms #linq-to-xml

#winforms #linq-to-xml

Вопрос:

В моем XML-файле есть 3 депозита, но запрос возвращает только первый депозит 3 раза. У меня есть pastd в классе Customer и файле XML. Это приложение .Net 4 Windows forms. Депозиты отображаются в форме, когда пользователь нажимает кнопку «ДЕПОЗИТЫ».

Метод формы пользовательского интерфейса, вызывающий класс Customer:

     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 amp; 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;
    }
 

Класс КЛИЕНТА

    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:

Ну, вы создаете один объект BL_Deposit oDeposit = new BL_Deposit(); , затем в своем цикле вы изменяете свойства того же объекта. Переместите код с созданием объекта в цикл, тогда, я думаю, вы должны получить то, что хотите.

Конечно, вы могли бы создавать объекты непосредственно в запросе, избегая анонимных объектов.

[править] Вот как вы можете использовать LINQ для непосредственного создания своего списка:

 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); .

Комментарии:

1. Извините, что я такой новичок, но не могли бы вы объяснить, как я могу создать объект непосредственно в запросе? Спасибо!