c# - How to fetch a model's relationship in a dynamic way? -
so have application makes use of sqlite database. have methods fetching models out of database. have repository communicaties database. , looks this:
public class photorepository { appdatabase db = null; public photorepository () { db = new appdatabase (constants.databasefilepath); } public photo getphoto(int id) { return db.getitem<photo>(id); } public ienumerable<photo> getphotos (int album_id) { return db.getitems<photo>().where( x => x.album_id == album_id ); } public int savephoto (photo item) { return db.saveitem<photo>(item); } public int deletephoto(int id) { return db.deleteitem<photo>(id); } }
i concerned getphotos(int album_id)
method, because method approaches in database class looks following:
public ienumerable<t> getitems<t> () t : bl.contracts.ibusinessentity, new () { lock (locker) { return (from in table<t> () select i).tolist (); } }
as can see, retrieves of photo models database , after i'm, filtering out corresponds right album_id
.
no question is:
how can rewrite method fetches out models corresponding album_id
. or better, how can rewrite method filter relationship on property?
so managed solve own answer. maybe people interested in result, here comes.
i read post dynamic linq queries. post talking can found here. first thing did making filter
class looks this:
public class filter { public enum op { equals, greaterthan, lessthan, greaterthanorequal, lessthanorequal, contains, startswith, endswith } public string propertyname { ; set ; } public op operation { ; set ; } public object value { ; set ; } }
then made expressionbuilder
class looks following:
public static class expressionbuilder { private static methodinfo containsmethod = typeof(string).getmethod("contains" ); private static methodinfo startswithmethod = typeof(string).getmethod("startswith", new type [] {typeof(string)}); private static methodinfo endswithmethod = typeof(string).getmethod("endswith", new type [] { typeof(string)}); public static expression<func<t, bool >> getexpression<t>(ilist<filter> filters) { if (filters.count == 0) return null ; parameterexpression param = expression.parameter(typeof (t), "t" ); expression exp = null ; if (filters.count == 1) exp = getexpression<t>(param, filters[0]); else if (filters.count == 2) exp = getexpression<t>(param, filters[0], filters[1]); else { while (filters.count > 0) { var f1 = filters[0]; var f2 = filters[1]; if (exp == null ) exp = getexpression<t>(param, filters[0], filters[1]); else exp = expression.andalso(exp, getexpression<t>(param, filters[0], filters[1])); filters.remove(f1); filters.remove(f2); if (filters.count == 1) { exp = expression .andalso(exp, getexpression<t>(param, filters[0])); filters.removeat(0); } } } return expression.lambda<func<t, bool>>(exp, param); } private static expression getexpression<t>(parameterexpression param, filter filter) { memberexpression member = expression.property(param, filter.propertyname); constantexpression constant = expression.constant(filter.value); switch (filter.operation) { case photowapp.dl.filter.op.equals: return expression.equal(member, constant); case photowapp.dl.filter.op.greaterthan: return expression.greaterthan(member, constant); case photowapp.dl.filter.op.greaterthanorequal: return expression.greaterthanorequal(member, constant); case photowapp.dl.filter.op.lessthan: return expression.lessthan(member, constant); case photowapp.dl.filter.op.lessthanorequal: return expression.lessthanorequal(member, constant); case photowapp.dl.filter.op.contains: return expression.call(member, containsmethod, constant); case photowapp.dl.filter.op.startswith: return expression.call(member, startswithmethod, constant); case photowapp.dl.filter.op.endswith: return expression.call(member, endswithmethod, constant); } return null ; } private static binaryexpression getexpression<t> (parameterexpression param, filter filter1, filter filter2) { expression bin1 = getexpression<t>(param, filter1); expression bin2 = getexpression<t>(param, filter2); return expression.andalso(bin1, bin2); } }
then added method getitems<t>(list<filter> filters)
looks following:
public ienumerable<t> getitems<t> (list<filter> filters) t : bl.contracts.ibusinessentity, new () { lock (locker) { var deleg = expressionbuilder.getexpression<t> (filters).compile (); return (from in table<t>().where(deleg) select i).tolist(); } }
and retrieve records need, used following code.
public ienumerable<photo> getphotos (int album_id) { list<filter> filters = new list<filter> () { new filter{ propertyname = "album_id", operation = filter.op.equals, value = album_id } }; return db.getitems<photo>(filters); }
now can filter nicely on properties need! nice part solution can use class , property filter on.
i hope useful somebody!
Comments
Post a Comment