Click here to Skip to main content
15,868,016 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
-I have a simple select statement (with a join) of two tables.
-While the reader is reading this, I'm creating a new instance, and then calling my classes that will contain the information from each of my table columns.
-Then, I'm adding this instance at the end of the list.

BUT after weeks of debugging, I've realized that for some reason, a new instance of 'd' in this case, isn't being created. So, each time it goes through retrieving the information from the classes, it simultaneously replaces the previous array in the list. This results in the same row being produced each time. Here is my code.

C#
public List<Donor> Get()
        {
            //Define fields
            List<Donor> donors = new List<Donor>();
            string query;
            OracleCommand cmd;
            OracleDataReader reader;

            query = "SELECT * FROM ldhc_accounts l JOIN donors d ON l.donor_id = d.id";
            conn.Open();
            cmd = new OracleCommand(query, conn);
            reader = cmd.ExecuteReader();

            while (reader.Read())
            {
                Donor d = new Donor();
                {
                    d.DonorId = Convert.ToInt32(reader["id"]);
                    d.FName = reader["fname"].ToString();
                    donors.Add(d);
                }

            }

            conn.Close();

            return donors;
        }



C# File:

C#
protected void get_donors_btn_Click(object sender, EventArgs e)
        {
            List<Donor> donors = a_oracle.Get();
            foreach(Donor item in donors)
            {
                get_donors.InnerHtml += "<li>"
                    + item.DonorId + " " 
                    + item.FName + " "
                    + "</li>";
            }
        }


Donors Class

C#
namespace FinalProj.Models
{
    public class Donor : ldhc
    {
        //Fields
        private static Int64 _donor_credit_card;
        private static int _donor_ccv;
        private static int _donor_expiry_month;
        private static int _donor_expiry_year;
        private static int _donor_amt;
        private static int _donor_rows;
        private static object _donor_id;

        //Methods
        public int Donor_Amt
        {
            get { return _donor_amt; }
            set { _donor_amt = value; }
        }

        public Int64 DonorCredit
        {
            get { return _donor_credit_card; }
            set { _donor_credit_card = value; }
        }

        public int DonorCCV
        {
            get { return _donor_ccv; }
            set { _donor_ccv = value; }
        }

        public int DonorExpMonth
        {
            get { return _donor_expiry_month; }
            set { _donor_expiry_month = value; }
        }
        
        public int DonorExpYear
        {
            get { return _donor_expiry_year; }
            set { _donor_expiry_year = value; }
        }

        public int DRows
        {
            get { return _donor_rows; }
            set { _donor_rows = value; }
        }

        public object DonorId
        {
            get { return _donor_id; }
            set { _donor_id = value; }
        }

        //public ldhc Ldhc { get; set; }
    }
}


What I have tried:

-I've tried to rearrange where my new instance is created, I've triple checked all my other code, and have finally realized that there is something here that is wrong.

-If I create a select statement and include a WHERE clause, it works perfectly and returns only a single row that I need.

-I've removed some other columns I'm trying to retrieve to make this code a little cleaner, but when I run this select statement in SQL developer, it works perfectly to return 3 distinct rows.

-I'm stumped. Stack Overflow is stumped (or it's too long winded of a question).

-Let me know if there's any other information you need.
Posted
Updated 23-Jan-18 6:26am
v5
Comments
Paulo Zemek 22-Jan-18 16:05pm    
This code looks fine... it has some odd scoping (why is there a new scope after Donor d = new Donor();?)

Is it possible that in your real code you are doing Donor d = new Donor() before the while? That would explain the issue (you would be reading and re-reading/replacing the contents on d, and adding the same d many times in the list, making it look like the last record, many times).

Edit: When I say fine I mean, I expect the code to work. I would suggest using "using" clauses for the command and the reader. Also it is preferably to declare variables with initialization in the same line, but those shouldn't affect the correctness of the code.
Member 13637561 22-Jan-18 16:12pm    
Thanks for the reply - I've cut and paste exactly what I have, and I'm positive that the new instance is created inside the while. I've been warned that my code can definitely use some polishing, but theoretically I know that this should work... I just don't know why it doesn't, or if I'm missing something else.
Paulo Zemek 22-Jan-18 16:20pm    
Who is calling Get()? Is it possible that the caller of Get() is actually doing something wrong?

As I see from your comment to OriginalGriff, it seems the data is being replaced (so, only the last row stays, not the first) and that would look more like what I expected if d was being created outside the loop.

Anyways, how are you checking that all rows are "the same"? I can imagine the caller of Get might be doing something wrong.
Member 13637561 22-Jan-18 16:30pm    
I've added the code for calling Get() - I'm pretty positive this isn't the problem, because I see the list getting populated with the same row each time with the previous function, so my C# is just displaying the list I've populated.

I can see in my debugger that all rows are the same - I wish I could record it and show you, but running through it, I see my row being called, then see the second row being called, and then the first row being replaced in the list.
Paulo Zemek 22-Jan-18 16:33pm    
Sorry, but you told me that you cut/paste exactly what you have... but this is definitely not true.

You pass an argument to a_oracle.Get() (that a_donor), yet the code you are showing for Get() doesn't receive any parameters.

So, that wouldn't even compile... so, did you really cut/paste exactly what you have?

In your Donor class, you've declared all of the fields as static.

That means there's only ever a single value for those fields, no matter how many instances of your class you create.

Remove the static modifier from the fields, and your code should work.
C#
public class Donor : ldhc
{
    //Fields
    private Int64 _donor_credit_card;
    private int _donor_ccv;
    private int _donor_expiry_month;
    private int _donor_expiry_year;
    private int _donor_amt;
    private int _donor_rows;
    private object _donor_id;

static (C# Reference) | Microsoft Docs[^]
 
Share this answer
 
Comments
Member 13637561 23-Jan-18 12:35pm    
YOU. Are my hero.
Words can't express how thankful I am to have finally found the answer to this problem.
Thank you!
Without access to your data, there isn't a lot we can do.
Something you can try - instead of a DataReader, use a DataAdapter, and fill a DataTable.
You can then use the debugger to see exactly how many rows you are getting returned and exactly what they contain. It's unlikely that the Donor constructor is returning the same instance each time - that would take some serious bending of the way object constructors work - so it's much more likely that the data returned appears identical on each row rather that re-using the same object instance.
 
Share this answer
 
v2
Comments
Member 13637561 22-Jan-18 16:05pm    
I will definitely try the DataAdapter, but from what I'm seeing in the debugger, it is going through each row, and the data is being collected. But after creating the new instance, and going through the data of the next row, the first item in the list is replaced with the new data, and so on...

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900