NullifyNetwork

The blog and home page of Simon Soanes
Skip to content
[ Log On ]

This is some code I wrote a little while back as an example OR mapper.  When inheriting from BaseDataDynamicEntity you can use the attribute [DataDynamic(“Name”)] to indicate the field name in the database and then use the class below to fetch data from the database or update it with any changes.

 

This is just an example though and doesn’t do the updating – but instead returns an array of string that can be used to look at what’s in the object now.  Return a set of SqlParameter’s and plug it into a stored procedure for a working example.

 

      public abstract class BaseDataDynamicEntity

      {

            /// <summary>

            /// An attribute to use to work out which properties have names that are in the database

            /// </summary>

            public class DataDynamic : Attribute

            {

                  public DataDynamic(string fieldName)

                  {

                        _fieldName = fieldName;

                  }

                  /// <summary>

                  /// The name of the field in the database

                  /// </summary>

                  public string FieldName

                  {

                        get

                        {

                              return _fieldName;

                        }

                  }

                  private string _fieldName = "";

            }

 

            /// <summary>

            /// Return a set of properties on this class as a demonstration of what is possible

            /// </summary>

            /// <returns></returns>

            public string[] ListDataProperties()

            {

                  Type t = this.GetType();

                  PropertyInfo[] p = t.GetProperties();

                  ArrayList properties = new ArrayList();

                  foreach (PropertyInfo pi in p)

                  {

                        if (pi.IsDefined(typeof(DataDynamic), true))

                        {

                              properties.Add(pi.Name+": "+pi.GetValue(this, null).ToString()); //could instead write these out to some parameters.

                        }

                  }

                  string[] values = new string[properties.Count];

                  properties.CopyTo(values);

                  return values;

            }

 

            /// <summary>

            /// Given an SqlDataReader from ExecuteReader, fetch a set of data and use it to fill the child objects properties

            /// </summary>

            /// <param name="dr"></param>

            public void SetDataProperties(SqlDataReader dr)

            {

                  while (dr.Read())

                  {

                        for (int i = 0; i<dr.FieldCount; i++)

                        {

                              setProperty(dr.GetName(i), dr.GetValue(i));

                        }

                  }

                  dr.Close();

            }

 

            private void setProperty(string name, object data)

            {

                  Type t = this.GetType();

                  PropertyInfo[] p = t.GetProperties();

                  foreach (PropertyInfo pi in p)

                  {

                        if (pi.IsDefined(typeof(DataDynamic), true)&&pi.CanWrite)

                        {

                              object[] fields = pi.GetCustomAttributes(typeof(DataDynamic), true);

                              foreach (DataDynamic d in fields)

                              {

                                    if (d.FieldName == name)

                                    {

                                          pi.SetValue(this, data, null);

                                    }

                              }

                             

                        }

                  }

            }

      }

 

And to use this, you do something like:

 

      public class NewsArticle: BaseDataDynamicEntity

      {

            private int _id = 5;

            /// <summary>

            /// The Id in the database

            /// </summary>

            [DataDynamic("id")]

            public int Id

            {

                  get

                  {

                        return _id;

                  }

                  set

                  {

                        _id = value;

                  }

            }

 

            private string _name = "Demo object";

            /// <summary>

            /// The name in the database

            /// </summary>

            [DataDynamic("subject")]

            public string Name

            {

                  get

                  {

                        return _name;

                  }

                  set

                  {

                        _name = value;

                  }

            }

      }

 

Which makes populating it as easy as:

 

SqlConnection sq = new SqlConnection("Data Source=(local);InitialCatalog=nullifydb;Integrated Security=SSPI;");

      sq.Open();

      SqlCommand sc = sq.CreateCommand();

      sc.CommandText = "SELECT TOP 1 * FROM newsarticle";

NewsArticle n = new NewsArticle();

      n.SetDataProperties(sc.ExecuteReader());

      sq.Close();

 

Obviously this is just an example, and you would want to use a DAL of some sort to do the data extraction, but integrating the DAL with the above technique should be fairly easy.

Permalink