How do write a generic function that takes a datarow and fill an object's properties?

。_饼干妹妹 提交于 2020-12-30 01:31:26

问题


I have some function like

private static UserInfo FillUserInfoFromDataRow(DataRow dr)
{

     UserInfo user = new UserInfo();

     user.UserID = (int) dr["UserID"];
     user.UserName = (int) dr["UserName"];
     user.ProjectID = (int) dr["ProjectID"];
     user.ClassID = (int) dr["ClassID"];
     ..............

     return user;
}

I'd like to write some generic function like private static T FillEntityInfoFromDataRow(DataRow dr), that will treat analogous types ProjectInfo, JobInfo, etc.

I can get all columns names of the DataRow parameter, but I don't know how to get all the appropriate fields of the generic T type and how to do appropriate casting. Is it some way to do this job? Thanks!

Ilan.


回答1:


Its better to make use of reflection there are no of example avaible on google to do this this.

Check the below example

namespace MyNamespace.Data
{
    class Converter
    {
        public static void Fill(object LogicObject, DataRow Row)
        {
            Dictionary<string, PropertyInfo> props = new Dictionary<string,PropertyInfo>();
            foreach (PropertyInfo p in LogicObject.GetType().GetProperties())
                props.Add(p.Name, p);
            foreach (DataColumn col in Row.Table.Columns)
            {
                string name = col.ColumnName;
                if (Row[name] != DBNull.Value && props.ContainsKey(name))
                {
                    object item = Row[name];
                    PropertyInfo p = props[name];
                    if (p.PropertyType != col.DataType)
                        item = Convert.ChangeType(item, p.PropertyType);
                    p.SetValue(LogicObject, item, null);
                }
            }

        }
    }
}

Check the full blog post : http://kasey-jo.blogspot.com/2009/04/using-reflection-to-fill-business-layer.html




回答2:


I use this, which is sort of like what you need:

EDITED thanks to Heinzi

    public virtual void LoadDataRow(DataRow drow, params string[] parameters)
    {
        this.LoadDataRow(drow);
        foreach (string property in parameters)
        {
            try
            {
                if (drow[property] != null)
                {
                    PropertyInfo pi = this.GetType().GetProperty(property);
                    if (pi != null && drow.Table.Columns.Contains(property))
                    {
                        pi.SetValue(this, drow[property], null);
                    }
                }
            }
            catch { throw; }
        }
    }

In your case though, you might want to loop through th eproperty collection of your object first, and try to load from your dataset, but th eabove code should get you started.

EDIT

Found this on MSDN:

System.Reflection.PropertyInfo[] p = MyObject.GetType.GetProperties();
foreach(System.Reflection.PropertyInfo prop in p)
{
  ....
}



回答3:


Delegate this functionality to each specific class itself by declaring abstarct method in base class. BTW, I suggest to name this method like CreateFromDataRow()

abstract class InfoBase
{
    public abstract InfoBase CreateFromDataRow(DataRow dr);
}

OR

abstract class InfoBase<T>
{
    public abstract T CreateFromDataRow(DataRow dr);
}


来源:https://stackoverflow.com/questions/6690501/how-do-write-a-generic-function-that-takes-a-datarow-and-fill-an-objects-proper

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!