2010-09-22 42 views
0

一种类我有这样解析在C#

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(); 
    } 
} 

我觉得代码不为我好。我可以写给类作为参数,所以,当我想加载数据我只是给查询类为parameter..example,我想喜欢代码:

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(); 
    } 

所以我真的足以称之为方法类似

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

你能不能给我一个答案或暗示.. 由于提前

+1

您是否考虑过利用ORM? – 2010-09-22 04:52:08

回答

0

我觉得,你在想什么可能不那么优雅解。因为

1)您可以使用反射,但可能导致性能较差。所以,最好不要去争取它,这是非常需要的。 2)另外,明天,如果结果集中要处理的列发生变化,那么无论如何你需要去调整代码,否则你的代码可能会失败。

所以,更好的是你可以像Ani所建议的那样去找一些ORM框架。

+0

是啊,我会尝试使用NHibernate ..感谢您的建议.. :) – 2010-09-23 01:56:08

6

有,你可以做到这样的事情与反思的方式,但我强烈建议您切换到使用ORM framewor k代替ADO.NET Entity FrameworkLinq to SQLNHibernate

您可能需要阅读:

+2

+1。为什么在完成了一百次这样的代码之后编写这种代码,开发人员实际上可以编写一些商业价值代码? – 2010-09-22 04:54:17

+0

同意 - 投入10%的时间来学习您选择的ORM,例如NHibernate,EF,ActiveRecord等,并专注于提供价值。看看http://ayende.com/Blog/archive/2008/11/21/stealing-from-your-client.aspx – 2010-09-22 04:59:17

0

如果我收到了你的问题的权利,那么你要寻找的是多态性。试试这个:

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

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

Animal和People类都会实现IType接口,它可以是一个空接口。

更好的设计是更改代码结构并将DataList方法移至IType,并在People和Animal类中相应地实现此方法。你可以看到不止一种方法去皮肤:)

+0

仍然不会有太多帮助 - 他想要设置的属性是该查询是子类的成员,而不是基类。创建一个可重用的方法,可以根据数据集中的结果设置对象的属性,而不必知道对象的类型,这很复杂。 – 2010-09-22 05:01:01

+0

如果这个类型是已知的(我们知道在这种情况下),那么在这里我没有看到任何问题。 – 2010-09-22 05:12:22

+0

感谢您的意见:) – 2010-09-23 01:58:29

1

你可以使用泛型。我认为可以这样做:

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

如果您必须为接受数据作为参数的每个类创建一个构造函数。您可以事件修改代码并使用DataAdapter填充DataTable,然后您可以创建一个接受DataRow作为参数的构造函数,以便您可以实例化具有不同数量元素的类。

但是,如果你得到了更多的复杂与此,我建议使用像LINQ到SQL,实体框架,NHibernate的一些ORM框架...

0

你可能有这样的事情,其中​​一个代表用于填充从数据读取器对象:

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

然后使用它是这样的:

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

不过说真的,你应该使用一个ORM。