Method instances of c DataTable transformed with different structured entity classes

  • 2020-05-24 06:01:26
  • OfStack

In the actual development process, or the data table structure provided by the third party company does not correspond to the entity class fields in our system. What shall we do if we encounter such situation? One might say that creating an entity object at transformation time, running through the data in the table row by row, is the end of instantiating the entity object. Yes, it works, but it's very inefficient. If you have hundreds of millions of data, you have to instantiate hundreds of millions of objects, so you can see how efficient it is.
So let's look at 1 for my entity class


/// <summary>
///  Concrete entity class, different from the data table 
/// </summary>
public class Person
{
    [DataField("user_name")]// Represents a field in a database table 
    public string UserName { set; get; }// Represents the field to be converted to 
    [DataField("pass_word")]
    public string PassWord { set; get; }
}

The details are commented in the code, below is the transformation class


[AttributeUsage(AttributeTargets.Property)]
public sealed class DataFieldAttribute : Attribute
{
    /// <summary>
    ///  The field name for the table 
    /// </summary>
    public string ColumnName { set; get; }

    public DataFieldAttribute(string columnName)
    {
        ColumnName = columnName;
    }
}

public static class DataConvert<T> where T : new()
{
    /// <summary>
    ///  will DataRow Line is converted into Entity
    /// </summary>
    /// <param name="dr"></param>
    /// <returns></returns>
    public static T ToEntity(DataRow dr)
    {
        T entity = new T();
        Type info = typeof(T);
        var members = info.GetMembers();
        foreach (var mi in members)
        {
            if (mi.MemberType == MemberTypes.Property)
            {
                // Read on the property DataField features 
                object[] attributes = mi.GetCustomAttributes(typeof(DataFieldAttribute), true);
                foreach (var attr in attributes)
                {
                    var dataFieldAttr = attr as DataFieldAttribute;
                    if (dataFieldAttr != null)
                    {
                        var propInfo = info.GetProperty(mi.Name);
                        if (dr.Table.Columns.Contains(dataFieldAttr.ColumnName))
                        {
                            // According to the ColumnName That will be dr The relative fields in the Entity attribute 
                            propInfo.SetValue(entity,
                                              Convert.ChangeType(dr[dataFieldAttr.ColumnName], propInfo.PropertyType),
                                              null);
                        }

                    }
                }
            }
        }
        return entity;
    }

    /// <summary>
    ///  will DataTable Converted to Entity The list of 
    /// </summary>
    /// <param name="dt"></param>
    /// <returns></returns>
    public static List<T> ToList(DataTable dt)
    {
        List<T> list = new List<T>(dt.Rows.Count);
        foreach (DataRow dr in dt.Rows)
        {
            list.Add(ToEntity(dr));
        }
        return list;
    }
}

Calling code:


DataTable dt = new DataTable();
dt.Columns.Add("user_name");
dt.Columns.Add("pass_word");// These are the fields in the table, and now you need to convert them into concrete instances of the entity class 
dt.Rows.Add("kingtiger","1");
dt.Rows.Add("wangbiao", "2");

var users = DataConvert<Person>.ToList(dt);
foreach (var user in users)
{
    Response.Write(user.UserName + "," + user.PassWord);
}

for (int i = 0; i < dt.Rows.Count; i++)
{
    Person p = DataConvert<Person>.ToEntity(dt.Rows[i]);
    Response.Write(p.UserName + "," + p.PassWord);
}


Related articles: