[Mono-list] Fun and games with Sqlite and System.Reflection

Robert Jordan robertj at gmx.net
Wed Apr 9 15:29:26 UTC 2014


How about checking whether the IgnoreAttribute is applied to
the property?

for (int i = 0; i < properties.Length - 1; i++) {
	// ignore props marked with [Ignore]
	if (properties[i].GetCustomAttributes(typeof(IgnoreAttribute), 
false).Length > 0)
		next;
}

Robert


On 09.04.2014 14:38, Paul Johnson wrote:
> Hi,
>
> I have a very simple SQLite database class which I'm using
> System.Reflection to serialise and use within my DBManager class.
>
> My class looks like this (it's a test case to try and get things working
> before I integrate it)
>
> public class dbclass
> {
>      [PrimaryKey]
>      public string Id { get; set; }
>
>      public string Test { get; set; }
>
>      public DateTime Today { get; set; }
>
>      [Ignore]
>      public List<string> ListTest { get; set; }
>
>      public override string ToString()
>      {
>          return string.Format("[dbclass: Id={0}, Test={1},
> ListTest={2}]", Id, Test, ListTest);
>      }
> }
> When I serialise this class, the Ignore attribute used for Sqlite is
> ignored as it's not a System.Reflection attribute. Without it, the
> List<T> tries to be processed and causes the code to crash as it has
> nothing in the database for it (and Lists are supported under SQlite
> anyway!)
>
> I've checked on MSDN and there doesn't seem to be an equivalent of the
> Ignore attribute which is a bit of a pain.
>
> Within my dbclass, is it possible to set the reflection attribute to
> something so I can intercept and ignore the property I need to ignore
> (in this case the List)?
>
> My code that does the processing looks like this (no giggling at the back!)
>
> using System;
> using System.Collections.Generic;
> using System.Reflection;
> using System.Linq.Expressions;
> using System.Text;
> using SQLite;
>
> public class dbclass
>      {
>          [PrimaryKey]
>          public string Id { get; set; }
>
>          public string Test { get; set; }
>
>          public DateTime Today { get; set; }
>
>          [Ignore]
>          public List<string> ListTest { get; set; }
>
>          public override string ToString()
>          {
>              return string.Format("[dbclass: Id={0}, Test={1},
> ListTest={2}]", Id, Test, ListTest);
>          }
>      }
>
>      class TestClass
>      {
>          public TestClass()
>          {
>              var db = new dbclass()
>              {
>                  Id = Guid.NewGuid().ToString(),
>                  Test = "Hello",
>                  Today = DateTime.Now
>              };
>              Console.WriteLine("{0}", GetInsertQuery(db));
>          }
>
>          private readonly Dictionary<Type, Func<Object, String>>
> queryBuilders = new Dictionary<Type, Func<object, string>>();
>
>          public string GetInsertQuery(Object entity)
>          {
>              var type = entity.GetType();
>              if (!queryBuilders.ContainsKey(type))
>              {
>                  var param = Expression.Parameter(typeof(Object),
> "entity");
>                  var typedObject = Expression.Variable(type, "obj");
>                  var stringBuilder =
> Expression.Variable(typeof(StringBuilder), "sb");
>
>                  var appendString =
> typeof(StringBuilder).GetMethod("Append", new[] { typeof(String) });
>                  var objectToString = typeof(Object).GetMethod("ToString");
>
>                  var code = new List<Expression>();
>                  code.Add(Expression.Assign(typedObject,
> Expression.Convert(param, type)));
>                  code.Add(Expression.Assign(stringBuilder,
> Expression.New(typeof(StringBuilder))));
>
>                  code.Add(Expression.Call(stringBuilder, appendString,
> Expression.Constant(string.Format("INSERT INTO {0} (", type.Name))));
>
>                  var properties = type.GetProperties();
>
>                  for (int i = 0; i < properties.Length - 1; i++)
>                  {
>                      code.Add(Expression.Call(stringBuilder,
> appendString, Expression.Constant(properties[i].Name)));
>                      code.Add(Expression.Call(stringBuilder,
> appendString, Expression.Constant(", ")));
>                  }
>
>                  code.Add(Expression.Call(stringBuilder, appendString,
> Expression.Constant(properties[properties.Length - 1].Name)));
>
>                  code.Add(Expression.Call(stringBuilder, appendString,
> Expression.Constant(") VALUES (")));
>
>                  for (int i = 0; i < properties.Length - 1; i++)
>                  {
>                      code.Add(Expression.Call(stringBuilder,
> appendString, Expression.Constant("'")));
>                      code.Add(Expression.Call(stringBuilder,
> appendString, Expression.Call(Expression.Property(typedObject,
> properties[i]), objectToString)));
>                      code.Add(Expression.Call(stringBuilder,
> appendString, Expression.Constant("', ")));
>                  }
>
>                  code.Add(Expression.Call(stringBuilder, appendString,
> Expression.Constant("'")));
>                  code.Add(Expression.Call(stringBuilder, appendString,
> Expression.Call(Expression.Property(typedObject,
> properties[properties.Length - 1]), objectToString)));
>                  code.Add(Expression.Call(stringBuilder, appendString,
> Expression.Constant("', ")));
>
>                  code.Add(Expression.Call(stringBuilder, appendString,
> Expression.Constant(");")));
>
>
>                  code.Add(Expression.Call(stringBuilder, "ToString", new
> Type[] { }));
>
>                  var expression = Expression.Lambda<Func<Object,
> String>>(Expression.Block(new[] { typedObject, stringBuilder }, code),
> param);
>                  queryBuilders[type] = expression.Compile();
>              }
>
>              string f = queryBuilders[type](entity);
>              return f;
>          }
>
> Dies if you add a List<T> into the class being passed in
>
> TIA
>
> Paul




More information about the Mono-list mailing list