0

i have code like this

public class People
{
    public string name { get; set; }
}

public class Animal
{
    public string age { get; set; }
}

class Test
{
    public void DataPeopleList()
    {
        string sql = "SELECT * FROM People"; 
        SqlCommand cmd = new SqlCommand(sql, conn); 
        SqlDataReader rdr = cmd.ExecuteReader();
        List<People> list = new List<People>();
        while (rdr.Read()) {
            People p = new People();
            p.name = rdr["name"].ToString();
            list.Add(p);
        } 
        rdr.Close();             
    }

    public void DataAnimalList()
    {
        string sql = "SELECT * FROM Animal";
        SqlCommand cmd = new SqlCommand(sql, conn);
        SqlDataReader rdr = cmd.ExecuteReader();
        List<People> list = new List<People>();
        while (rdr.Read())
        {
            People p = new People();
            p.name = rdr["age"].ToString();
            list.Add(p);
        }
        rdr.Close();
    }
}

i think is not good for me. can i write give class as parameter so when i want load data i just give query and class as parameter..example the code which i want like :

public void LoadData(string query, Type ClassName)
    {
        SqlCommand cmd = new SqlCommand(sql, conn);
        SqlDataReader rdr = cmd.ExecuteReader();
        List<ClassName> list = new List<ClassName>();
        while (rdr.Read())
        {
            ClassName p = new ClassName();
            //p.name = rdr["age"].ToString(); i dont have idea in this part
            list.Add(p);
        }
        rdr.Close();
    }

so I`m enough to call method like

public void DataAnimalList()
    {
        string sql = "SELECT * FROM Animal";
        LoadData(sql,class Animal);
    }

Can you give me an answer or hint.. Thanks in Advance

5 Answers5

6

There are ways that you can accomplish something like this with reflection, but I strongly recommend you switch to using an ORM framework like ADO.NET Entity Framework, Linq to SQL or NHibernate instead.

You might want to read:

Community
  • 1
  • 1
Ani
  • 111,048
  • 26
  • 262
  • 307
  • 2
    +1. Why write this kind of code when it's all been done a hundred times over, and devs can actually write some code of business value? – p.campbell Sep 22 '10 at 04:54
  • Agree - invest 10% of the time in learning the ORM of your choice, such as NHibernate, EF, ActiveRecord etc, and focus on delivering value. Have a look at http://ayende.com/Blog/archive/2008/11/21/stealing-from-your-client.aspx – Michael Shimmins Sep 22 '10 at 04:59
1

You could use generics. I think it can be done like this:

public List<T> LoadData<T> (String query) {
    SqlCommand cmd = new SqlCommand(query, conn);
    SqlDataReader rdr = cmd.ExecuteReader();
    List<T> list = new List<T>();
    while (rdr.Read())
    {
        T p = new T(rdr[0]);
        list.Add(p);
    }
    rdr.Close();

    return list;
}

Where you have to create a constructor for each class that accepts the data as a parameter. You could event modify the code a bit and use a DataAdapter to fill a DataTable, and then you could create a constructor that accepts DataRow as argument so you can instantiate classes with different number of elements.

But if you get a any more complicated with this, I would suggest using some ORM framework like Linq to SQL, Entity Framework, Nhibernate...

skajfes
  • 8,125
  • 2
  • 24
  • 23
0

If I got your question right then what you're looking for is Polymorphism. Try this:

void DataList(IType var)
{
  if(IType is Animal)
  {
    //Do something for Animal
  }

  if(IType is People)
  {
    //Do something for People
  }
}

Both Animal and People class would implement IType interface, which can be an empty interface.

A better design would be to change your code structure and move the DataList method to IType and implement this accordingly in your People and Animal class. More than one way to skin the cat, you see :)

Sidharth Panwar
  • 4,606
  • 6
  • 27
  • 36
  • Still won't help too much - the properties he wants to set as a result of the query are members of the sub classes, not the base class. Creating a reusable method that can set the properties on an object from the results in a dataset, without knowing the type of the object is complicated. – Michael Shimmins Sep 22 '10 at 05:01
  • If the type is known (which we do know in this case) then I don't see any problem here. – Sidharth Panwar Sep 22 '10 at 05:12
0

I feel, what you are thinking may not be that elegant solution. Because

1) You can use reflection but which can result in poor performance. So, better not to go for it until, it is badly needed.

2) Also, tomorrow, if the columns to deal with in the result set changes then anyway you need to go and tweak the code otherwise your code may fail.

So, better could be you can go for some ORM Framework as suggested by Ani.

Siva Gopal
  • 3,474
  • 1
  • 25
  • 22
0

You could have something like this where a delegate is used to populate the object from the data reader:

public List<T> LoadData<T>(string sql, Action<IDataReader, T> fill) where T : new()
{
  using( SqlCommand cmd = new SqlCommand(sql, conn) )
  using( SqlDataReader reader = cmd.ExecuteReader() )
  {
    List<T> items = new List<T>();
    while( reader.Read() )
    {
      T item = new T();
      fill(reader, item);
      items.Add(item);
    }
    return items;
  }
}

Then use it like this:

public List<Person> LoadPeople()
{
    return LoadData<Person>("SELECT * FROM Person", (r, p) => 
    {
      p.Name = r["Name"].ToString();
    });
}

But really you should be using an ORM.

Andrew Kennan
  • 13,947
  • 3
  • 24
  • 33