Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 997
Ilan Avatar asked Dec 16 '22 11:12

Ilan


2 Answers

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

like image 134
Pranay Rana Avatar answered Dec 19 '22 01:12

Pranay Rana


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)
{
  ....
}
like image 25
Oxonhammer Avatar answered Dec 19 '22 00:12

Oxonhammer