[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