Wrox Programmer Forums

Need to download code?

View our list of code downloads.

Go Back   Wrox Programmer Forums > C# and C > C# 2005 > C# 2005
Password Reminder
Register
| FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read
C# 2005 For discussion of Visual C# 2005.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the C# 2005 section of the Wrox Programmer to Programmer discussions. This is a community of tens of thousands of software programmers and website developers including Wrox book authors and readers. As a guest, you can read any forum posting. By joining today you can post your own programming questions, respond to other developers’ questions, and eliminate the ads that are displayed to guests. Registration is fast, simple and absolutely free .
DRM-free e-books 300x50
 
 
Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old June 13th, 2007, 01:41 PM
Registered User
 
Join Date: Jun 2007
Location: , , .
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Default Loading data into List<T>

How do I load data from an SQL database into a List<T> generic? I was thinking of creating a business object that inherits from List<T> but I can't seem to get it to work. The book is good at explaining the basics of this but I'm still not sure how I would use this kind of a generic in a real-world application. Is this something Microsoft forgot to handle?

  #2 (permalink)  
Old June 13th, 2007, 02:39 PM
planoie's Avatar
Friend of Wrox
Points: 16,481, Level: 55
Points: 16,481, Level: 55 Points: 16,481, Level: 55 Points: 16,481, Level: 55
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Aug 2003
Location: Clifton Park, New York, USA.
Posts: 5,407
Thanks: 0
Thanked 16 Times in 16 Posts
Default

List<T> is the generic definition of the list, but you must specify the type you will use for the instance of the list. Decide what business class you want to use and create an instance of the list with your type as the type parameter:

List<MyBusinessClass> myList = new List<MyBusinessClass>();
MyBusinessClass myClassInstance;

myClassInstance = new MyBusinessClass();
//populate the instance members
myList.Add(myClassInstance);
//loop as needed


You can certainly extend List<T> if you wish as well. This is a good method of creating a custom collection. When you extend it, you can define the type of the list you are extending and all the List methods will apply that type parameter. This creates a strongly typed collection from a generic collection.

public class MyBusinessClassList : List<MyBusinessClass>{
   // add your members here
}

Alternatively, if you want to add capabilities to a generic list, but still maintain the generic capability, you can define your own generic type that derives from List<T>:

public class MyBusinessClassList<T> : List<T>{
   // add your members here
}

In this case however, you are still working in the context of a generic type, so you are limited in what you can do. However, if you constrain your definition you can work with some base type or interface.

-Peter
  #3 (permalink)  
Old June 13th, 2007, 02:50 PM
Imar's Avatar
Wrox Author
Points: 72,055, Level: 100
Points: 72,055, Level: 100 Points: 72,055, Level: 100 Points: 72,055, Level: 100
Activity: 100%
Activity: 100% Activity: 100% Activity: 100%
 
Join Date: Jun 2003
Location: Utrecht, Netherlands.
Posts: 17,086
Thanks: 80
Thanked 1,587 Times in 1,563 Posts
Default

Hi rvincent,

You may want to take a look at my article series about N-Layer design. The series deals with List<T> classes and other design and data access issues. You find part 1 here:

http://Imar.Spaanjaars.Com/QuickDocId.aspx?quickdoc=416

Cheers,

Imar
  #4 (permalink)  
Old June 13th, 2007, 07:34 PM
Registered User
 
Join Date: Jun 2007
Location: , , .
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Quote:
quote:Originally posted by planoie
snip
I guess I need to explain further. Here's what I've created:

using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;
using GeoRange;

namespace GeoRange
{
    public class Targets : List<Target>
    {
        public List<Target> Load()
        {
            List<Target> data = new List<Target>();

            string connectionString = @"Server=E17818\SQLEXPRESS;Database=test;Trusted_C onnection=true";

            SqlConnection myConnection = new SqlConnection(connectionString);

            SqlCommand myCommand = new SqlCommand("SELECT Name FROM Targets", myConnection);

            myConnection.Open();

            SqlDataReader reader = myCommand.ExecuteReader();

            while (reader.Read())
            {
                Target Target1 = new Target();

                Target1.Name = reader["Name"] as string;

                //Target.X = reader["X"] as double;

                //Target.Y = reader["Y"] as double;

                data.Add(Target1);
            }

            myConnection.Close();

            myCommand.Dispose();

            return data; // not returning the List

        }
    }
}

//++++++++++++++++++++++++++++++++++++++++++++++++++ +++
//++++++++++++++++++++++++++++++++++++++++++++++++++ +++


using System;
using System.Collections.Generic;
using System.Text;

namespace GeoRange
{
    public class Target
    {
        private string _name;
        private double _X;
        private double _Y;

        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }
        public double X
        {
            get
            {
                return _X;
            }
            set
            {
                _X = value;
            }
        }

        public double Y
        {
            get
            {
                return _Y;
            }
            set
            {
                _Y = value;
            }
        }

        public Target()
        {
        }

        public Target(string name, double X, double Y)
        {
            this._name = name;
            this._X = X;
            this._Y = Y;

        }



        }
    }

//++++++++++++++++++++++++++++++++++++++++++++++++++ +++
//++++++++++++++++++++++++++++++++++++++++++++++++++ +++

I then try to use these from a button on a form:

        private void button1_Click(object sender, EventArgs e)
        {

            List<Target> Targets = new List<Target>();

            Targets targetList = new Targets();
            targetList.Load();

            foreach (Target theTarget in targetList)
            {
                comboBox1.Items.Add(theTarget.Name);
            }

            //MessageBox.Show(Target1.Name, "A caption");
        }

This last part is the problem. targetList isn't returning the list. Anyone know why?

  #5 (permalink)  
Old June 14th, 2007, 02:43 AM
joefawcett's Avatar
Wrox Author
Points: 9,763, Level: 42
Points: 9,763, Level: 42 Points: 9,763, Level: 42 Points: 9,763, Level: 42
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Jun 2003
Location: Exeter, , United Kingdom.
Posts: 3,074
Thanks: 1
Thanked 38 Times in 37 Posts
Default

That is the most confusing few lines of code I've ever seen.
You create a new class Targets, which derives from List<Target>. You then create an instance of List<Target> also called Targets. You then create an instance of Targets called targetList.
You then do
Code:
foreach (Target theTarget in targetList)
where you create an instance of Target called theTarget for each Target in targetList.

My head's spinning...

Your method Load returns a List<Target> but you don't actually save the return when you call it.
Why don't you store the data in a private List<Target> instead of returning it?
Have you stepped through the Load method to see if data is being populated?



--

Joe (Microsoft MVP - XML)
  #6 (permalink)  
Old June 14th, 2007, 08:52 AM
planoie's Avatar
Friend of Wrox
Points: 16,481, Level: 55
Points: 16,481, Level: 55 Points: 16,481, Level: 55 Points: 16,481, Level: 55
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Aug 2003
Location: Clifton Park, New York, USA.
Posts: 5,407
Thanks: 0
Thanked 16 Times in 16 Posts
Default

Quick Joe! Bite the rope, BITE THE ROPE!! ;)

rvincent,

Joe has a point... Your code is a little confusing. That's the reason I use variable prefixing. I try to avoid naming variables with names that could conflict with class names (if not programmatically, then humanly).

As far as the problem goes... you need to either load the list you are extending or handle the return value of the Load() method as Joe mentioned.

I think what you need is this:
Code:
namespace GeoRange
{
    public class Targets : List<Target>
    {
        public Targets Load()
        {
            //you are deriving a list so don't create one internally
            <s>List<Target> data = new List<Target>();</s>
            ...
            while (reader.Read())
            {
                Target Target1 = new Target();
                ...
                this.Add(Target1); // Add the Target to the derived list.
            }
            ...
            return this; //return myself, even though we don't really need to
        }
    }
}

    private void button1_Click(object sender, EventArgs e)
    {
        //this was redundant
        <s>List<Target> Targets = new List<Target>();</s>

        Targets targetList = new Targets();
        //because the Load method loads the object itself,
        //you don't really need to do anything with the return value
        targetList.Load(); 
        ...
    }
-Peter
  #7 (permalink)  
Old June 14th, 2007, 10:17 AM
Registered User
 
Join Date: Jun 2007
Location: , , .
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Quote:
quote:Originally posted by joefawcett
 That is the most confusing few lines of code I've ever seen.
You create a new class Targets, which derives from List<Target>. You then create an instance of List<Target> also called Targets. You then create an instance of Targets called targetList.
You then do
Code:
foreach (Target theTarget in targetList)
where you create an instance of Target called theTarget for each Target in targetList.

My head's spinning...

Your method Load returns a List<Target> but you don't actually save the return when you call it.
Why don't you store the data in a private List<Target> instead of returning it?
Have you stepped through the Load method to see if data is being populated?



--

Joe (Microsoft MVP - XML)
Well, I am just learning. Thanks for making me feel like an idiot.

  #8 (permalink)  
Old June 14th, 2007, 10:20 AM
Registered User
 
Join Date: Jun 2007
Location: , , .
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Quote:
quote:Originally posted by planoie
 Quick Joe! Bite the rope, BITE THE ROPE!! ;)

rvincent,

Joe has a point... Your code is a little confusing. That's the reason I use variable prefixing. I try to avoid naming variables with names that could conflict with class names (if not programmatically, then humanly).

As far as the problem goes... you need to either load the list you are extending or handle the return value of the Load() method as Joe mentioned.

I think what you need is this:
Code:
namespace GeoRange
{
    public class Targets : List<Target>
    {
        public Targets Load()
        {
            //you are deriving a list so don't create one internally
            <s>List<Target> data = new List<Target>();</s>
            ...
            while (reader.Read())
            {
                Target Target1 = new Target();
                ...
                this.Add(Target1); // Add the Target to the derived list.
            }
            ...
            return this; //return myself, even though we don't really need to
        }
    }
}

    private void button1_Click(object sender, EventArgs e)
    {
        //this was redundant
        <s>List<Target> Targets = new List<Target>();</s>

        Targets targetList = new Targets();
        //because the Load method loads the object itself,
        //you don't really need to do anything with the return value
        targetList.Load(); 
        ...
    }
-Peter
Thanks. That really helps me as I learn this.

  #9 (permalink)  
Old June 14th, 2007, 11:27 AM
joefawcett's Avatar
Wrox Author
Points: 9,763, Level: 42
Points: 9,763, Level: 42 Points: 9,763, Level: 42 Points: 9,763, Level: 42
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Jun 2003
Location: Exeter, , United Kingdom.
Posts: 3,074
Thanks: 1
Thanked 38 Times in 37 Posts
Default

Quote:
quote:Originally posted by rvincent

Well, I am just learning. Thanks for making me feel like an idiot.

That wasn't my intention, I was pointing out how difficult it is to follow the code the way it is written. If you are just beginning you have started with a fairly advanced topic, generics, inheritance and data access.
I would question the value of the derived class at all. You are tying yourself down somewhat especially having a SQL connection inside the class.
I would just use a List<T> to hold the Target instances. I would then have a helper class to perform the data access and return the appropriate DataReader. You can then loop through the reader and create the separate Target instances and add them to List<Target>:
Code:
DataReader dr = GetTargetDataReader(); //implement this method.
List<Target> targets = new List<Target>();
/*Loop through dr and for each row create a Target*/
while (dr.Read())
{
   Target target = new Target();
   target.Name = reader["Name"] as string;
   targets.Add(target);
}
Alternatively go with your derived class TargetList deriving from List<Target> but change the Load method to accept a DataReader, this is a more flexible solution. During Load you just add Target instances to the underlying list by using the Add method.
Another option would be to write your own Collection class that just delegates all calls to a private List<Target>.

--

Joe (Microsoft MVP - XML)
 


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
generic List<T> Sort() shadowcodes C# 2005 2 February 15th, 2007 01:30 PM
How to implement a function return List<T> jdang67 C# 2005 2 January 30th, 2006 11:28 AM
<style> tags in a <body> vs. <div> bcat BOOK: Beginning CSS: Cascading Style Sheets for Web Design ISBN: 978-0-7645-7642-3 1 March 27th, 2005 08:50 AM
<marquee><b>About CHAT App. in PHP4</b></marquee> Ramkrishna PHP How-To 1 September 11th, 2004 07:01 AM
the book <<Data-Centric.net programing with c#>> jamxx All Other Wrox Books 0 November 18th, 2003 10:56 PM



All times are GMT -4. The time now is 10:22 AM.


Powered by vBulletin®
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.
© 2013 John Wiley & Sons, Inc.