c# - How to get the where clause from IQueryable defined as interface -


  class program {     static void main(string[] args)     {         var c = new sampleclass<classstring>();         c.classstrings.add(new classstring{ name1 = "1", name2 = "1"});         c.classstrings.add(new classstring{ name1 = "2", name2 = "2"});          var result = c.query<classstring>().where(s => s.name1.equals("2"));          console.writeline(result);         console.readline();     } }  public class classstring {     public string name1 { get; set; }     public string name2 { get; set; } }    public interface isampleq {     iqueryable<t> query<t>() t: class , new(); } public class sampleclass<x> : isampleq {     public list<x> classstrings { get; private set; }      public sampleclass()     {         classstrings = new list<x>();     }       public iqueryable<t> query<t>() t : class, new()     {         //get expression here.         return new enumerablequery<t>((ienumerable<t>) classstrings);     } } 

i looked solution1, solution2 , solution3 seems not applicable question. since clause defined outside , interface of class. how expression inside query method? since no variable being pass thru.

the purpose, want retrieve , injected destination (which dbcontext iqueryable). because have common interface isampleq.


added new sample codes same scenario:

 internal class program {     private static void main(string[] args)     {         var oracledbcontext = new oracledbcontext();         var result = oracledbcontext.query<person>().where(person => person.name.equals("username"));          console.writeline();         console.readline();     } }  public interface igenericquery {     iqueryable<t> query<t>() t : class , new(); }  public class oracledbcontext : igenericquery {     public oracledbcontext()     {         //will hold oracle operations here. brevity,         //query exposed.     }      public iqueryable<t> query<t>() t : class, new()     {         //get predicate here. since defined outside of         //class. want retrieve since iqueryable<t> generic both class         //oracledbcontext , mssqldbcontext. want re-inject or add          //new expression before calling.         //         //for eg.         //oracledbcontext.query<t>(where clause here)         return null;     } }  public class mssqldbcontext : igenericquery {     public mssqldbcontext()     {         //will hold mssql operations here. brevity,         //query exposed.     }      public iqueryable<t> query<t>() t : class, new()     {         //get predicate here.         return null;     } }  public class person {     public int id { get; set; }     public int name { get; set; } } 

it quite complex... now... queryable.where() works way:

public static iqueryable<tsource> where<tsource>(this iqueryable<tsource> source, expression<func<tsource, bool>> predicate) {     return source.provider.createquery<tsource>(expression.call(null, ...  

so queryable.where calls source.provider.createquery() retuns new iqueryable<>. if want able "see" where() while being added (and manipulate it), must "be" iqueryable<>.provider, , have createquery(), must create class implements iqueryprovider (and class implements iqueryable<t>).

another way (much simpler) have simple query "converter": method accepts iqueryable<> , returns manipulated iqueryable<>:

var result = c.query<classstring>().where(s => s.name1.equals("2")).fixmyquery(); 

as said, full route quite long:

namespace utilities {     using system;     using system.collections;     using system.collections.generic;     using system.collections.objectmodel;     using system.data.entity;     using system.data.entity.infrastructure;     using system.linq;     using system.linq.expressions;     using system.reflection;     using system.threading;     using system.threading.tasks;      public class proxydbcontext : dbcontext     {         protected static readonly methodinfo proxifysetsmethod = typeof(proxydbcontext).getmethod("proxifysets", bindingflags.instance | bindingflags.nonpublic);          protected static class proxydbcontexsetter<tcontext> tcontext : proxydbcontext         {             public static readonly action<tcontext> = x => { };              static proxydbcontexsetter()             {                 var properties = typeof(tcontext).getproperties(bindingflags.instance | bindingflags.public | bindingflags.flattenhierarchy);                  parameterexpression context = expression.parameter(typeof(tcontext), "context");                  fieldinfo manipulatorfield = typeof(proxydbcontext).getfield("manipulator", bindingflags.instance | bindingflags.public);                 expression manipulator = expression.field(context, manipulatorfield);                  var sets = new list<expression>();                  foreach (propertyinfo property in properties)                 {                     if (property.getmethod == null)                     {                         continue;                     }                      methodinfo setmethod = property.setmethod;                     if (setmethod != null && !setmethod.ispublic)                     {                         continue;                     }                      type type = property.propertytype;                     type entitytype = getidbsettypeargument(type);                      if (entitytype == null)                     {                         continue;                     }                      if (!type.isassignablefrom(typeof(dbset<>).makegenerictype(entitytype)))                     {                         continue;                     }                      type dbsettype = typeof(dbset<>).makegenerictype(entitytype);                      constructorinfo constructor = typeof(proxydbset<>)                         .makegenerictype(entitytype)                         .getconstructor(new[]                      {                          dbsettype,                          typeof(func<bool, expression, expression>)                      });                      memberexpression property2 = expression.property(context, property);                     binaryexpression assign = expression.assign(property2, expression.new(constructor, expression.convert(property2, dbsettype), manipulator));                      sets.add(assign);                 }                  expression<action<tcontext>> lambda = expression.lambda<action<tcontext>>(expression.block(sets), context);                 = lambda.compile();             }              // gets t of idbsetlt;t&gt;             private static type getidbsettypeargument(type type)             {                 ienumerable<type> interfaces = type.isinterface ?                     new[] { type }.concat(type.getinterfaces()) :                     type.getinterfaces();                  type argument = (from x in interfaces                                  x.isgenerictype                                  let gt = x.getgenerictypedefinition()                                  gt == typeof(idbset<>)                                  select x.getgenericarguments()[0]).singleordefault();                 return argument;             }         }          public readonly func<bool, expression, expression> manipulator;          /// <summary>         ///          /// </summary>         /// <param name="manipulator">first parameter: true execute, false createquery.</param>         /// <param name="resetsets">true have dbset&lt;tentity&gt; , idbset&lt;tentity&gt; proxified</param>         public proxydbcontext(func<bool, expression, expression> manipulator, bool resetsets = true)         {             manipulator = manipulator;              if (resetsets)             {                 proxifysetsmethod.makegenericmethod(gettype()).invoke(this, null);             }         }          /// <summary>         ///          /// </summary>         /// <param name="nameorconnectionstring"></param>         /// <param name="manipulator">first parameter: true execute, false createquery.</param>         /// <param name="resetsets">true have dbset&lt;tentity&gt; , idbset&lt;tentity&gt; proxified</param>         public proxydbcontext(string nameorconnectionstring, func<bool, expression, expression> manipulator, bool resetsets = true)             : base(nameorconnectionstring)         {             manipulator = manipulator;              if (resetsets)             {                 proxifysetsmethod.makegenericmethod(gettype()).invoke(this, null);             }         }          protected void proxifysets<tcontext>() tcontext : proxydbcontext         {             proxydbcontexsetter<tcontext>.do((tcontext)this);         }          public override dbset<tentity> set<tentity>()         {             return new proxydbset<tentity>(base.set<tentity>(), manipulator);         }          public override dbset set(type entitytype)         {             dbset set = base.set(entitytype);             constructorinfo constructor = typeof(proxydbsetnongeneric<>)                 .makegenerictype(entitytype)                 .getconstructor(new[]                  {                      typeof(dbset),                      typeof(func<bool, expression, expression>)                  });              return (dbset)constructor.invoke(new object[] { set, manipulator });         }     }      /// <summary>     /// dbset, implemented internaldbset&lt&gt; ef.     /// </summary>     /// <typeparam name="tentity"></typeparam>     public class proxydbsetnongeneric<tentity> : dbset, iqueryable<tentity>, ienumerable<tentity>, idbasyncenumerable<tentity>, iqueryable, ienumerable, idbasyncenumerable tentity : class     {         protected readonly dbset basedbset;         protected readonly iqueryable<tentity> proxyqueryable;          public readonly func<bool, expression, expression> manipulator;          protected readonly fieldinfo internalsetfield = typeof(dbset).getfield("_internalset", bindingflags.instance | bindingflags.nonpublic);          /// <summary>         ///          /// </summary>         /// <param name="basedbset"></param>         /// <param name="manipulator">first parameter: true execute, false createquery.</param>         public proxydbsetnongeneric(dbset basedbset, func<bool, expression, expression> manipulator)         {             basedbset = basedbset;              iqueryprovider provider = ((iqueryable)basedbset).provider;             proxydbprovider proxydbprovider = new proxydbprovider(provider, manipulator);              proxyqueryable = proxydbprovider.createquery<tentity>(((iqueryable)basedbset).expression);             manipulator = manipulator;              if (internalsetfield != null)             {                 internalsetfield.setvalue(this, internalsetfield.getvalue(basedbset));             }         }          /// <summary>         ///          /// </summary>         /// <param name="basedbset"></param>         /// <param name="proxyqueryable"></param>         /// <param name="manipulator">first parameter: true execute, false createquery.</param>         public proxydbsetnongeneric(dbset basedbset, proxyqueryable<tentity> proxyqueryable, func<bool, expression, expression> manipulator)         {             basedbset = basedbset;              proxyqueryable = proxyqueryable;             manipulator = manipulator;              if (internalsetfield != null)             {                 internalsetfield.setvalue(this, internalsetfield.getvalue(basedbset));             }         }          public override object add(object entity)         {             return basedbset.add(entity);         }          public override ienumerable addrange(ienumerable entities)         {             return basedbset.addrange(entities);         }          public override dbquery asnotracking()         {             return new proxydbsetnongeneric<tentity>(basedbset, new proxyqueryable<tentity>((proxydbprovider)proxyqueryable.provider, (iqueryable<tentity>)basedbset.asnotracking()), manipulator);         }          [obsolete]         public override dbquery asstreaming()         { #pragma warning disable 618             return new proxydbsetnongeneric<tentity>(basedbset, new proxyqueryable<tentity>((proxydbprovider)proxyqueryable.provider, (iqueryable<tentity>)basedbset.asstreaming()), manipulator); #pragma warning restore 618         }          public override object attach(object entity)         {             return basedbset.attach(entity);         }          public override object create(type derivedentitytype)         {             return basedbset.create(derivedentitytype);         }          public override object create()         {             return basedbset.create();         }          public override object find(params object[] keyvalues)         {             return basedbset.find(keyvalues);         }          public override task<object> findasync(cancellationtoken cancellationtoken, params object[] keyvalues)         {             return basedbset.findasync(cancellationtoken, keyvalues);         }          public override task<object> findasync(params object[] keyvalues)         {             return basedbset.findasync(keyvalues);         }          public override dbquery include(string path)         {             return new proxydbsetnongeneric<tentity>(basedbset, new proxyqueryable<tentity>((proxydbprovider)proxyqueryable.provider, (iqueryable<tentity>)basedbset.include(path)), manipulator);         }          public override ilist local         {                         {                 return basedbset.local;             }         }          public override object remove(object entity)         {             return basedbset.remove(entity);         }          public override ienumerable removerange(ienumerable entities)         {             return basedbset.removerange(entities);         }          public override dbsqlquery sqlquery(string sql, params object[] parameters)         {             return basedbset.sqlquery(sql, parameters);         }          ienumerator<tentity> ienumerable<tentity>.getenumerator()         {             return proxyqueryable.getenumerator();         }          ienumerator ienumerable.getenumerator()         {             return ((ienumerable)proxyqueryable).getenumerator();         }          type iqueryable.elementtype         {             { return proxyqueryable.elementtype; }         }          expression iqueryable.expression         {             { return proxyqueryable.expression; }         }          iqueryprovider iqueryable.provider         {             { return proxyqueryable.provider; }         }          idbasyncenumerator<tentity> idbasyncenumerable<tentity>.getasyncenumerator()         {             return ((idbasyncenumerable<tentity>)proxyqueryable).getasyncenumerator();         }          idbasyncenumerator idbasyncenumerable.getasyncenumerator()         {             return ((idbasyncenumerable)proxyqueryable).getasyncenumerator();         }          public override string tostring()         {             return proxyqueryable.tostring();         }     }      public class proxydbset<tentity> : dbset<tentity>, iqueryable<tentity>, ienumerable<tentity>, idbasyncenumerable<tentity>, iqueryable, ienumerable, idbasyncenumerable tentity : class     {         protected readonly dbset<tentity> basedbset;         protected readonly iqueryable<tentity> proxyqueryable;          public readonly func<bool, expression, expression> manipulator;          protected readonly fieldinfo internalsetfield = typeof(dbset<tentity>).getfield("_internalset", bindingflags.instance | bindingflags.nonpublic);          /// <summary>         ///          /// </summary>         /// <param name="basedbset"></param>         /// <param name="manipulator">first parameter: true execute, false createquery.</param>         public proxydbset(dbset<tentity> basedbset, func<bool, expression, expression> manipulator)         {             basedbset = basedbset;              iqueryprovider provider = ((iqueryable)basedbset).provider;             proxydbprovider proxydbprovider = new proxydbprovider(provider, manipulator);              proxyqueryable = proxydbprovider.createquery<tentity>(((iqueryable)basedbset).expression);             manipulator = manipulator;              if (internalsetfield != null)             {                 internalsetfield.setvalue(this, internalsetfield.getvalue(basedbset));             }         }          /// <summary>         ///          /// </summary>         /// <param name="basedbset"></param>         /// <param name="proxyqueryable"></param>         /// <param name="manipulator">first parameter: true execute, false createquery.</param>         public proxydbset(dbset<tentity> basedbset, proxyqueryable<tentity> proxyqueryable, func<bool, expression, expression> manipulator)         {             basedbset = basedbset;              proxyqueryable = proxyqueryable;             manipulator = manipulator;              if (internalsetfield != null)             {                 internalsetfield.setvalue(this, internalsetfield.getvalue(basedbset));             }         }          public override tentity add(tentity entity)         {             return basedbset.add(entity);         }          public override ienumerable<tentity> addrange(ienumerable<tentity> entities)         {             return basedbset.addrange(entities);         }          public override dbquery<tentity> asnotracking()         {             return new proxydbset<tentity>(basedbset, new proxyqueryable<tentity>((proxydbprovider)proxyqueryable.provider, basedbset.asnotracking()), manipulator);         }          [obsolete]         public override dbquery<tentity> asstreaming()         { #pragma warning disable 618             return new proxydbset<tentity>(basedbset, new proxyqueryable<tentity>((proxydbprovider)proxyqueryable.provider, basedbset.asstreaming()), manipulator); #pragma warning restore 618         }          public override tentity attach(tentity entity)         {             return basedbset.attach(entity);         }          public override tderivedentity create<tderivedentity>()         {             return basedbset.create<tderivedentity>();         }          public override tentity create()         {             return basedbset.create();         }          public override tentity find(params object[] keyvalues)         {             return basedbset.find(keyvalues);         }          public override task<tentity> findasync(cancellationtoken cancellationtoken, params object[] keyvalues)         {             return basedbset.findasync(cancellationtoken, keyvalues);         }          public override task<tentity> findasync(params object[] keyvalues)         {             return basedbset.findasync(keyvalues);         }          public override dbquery<tentity> include(string path)         {             return new proxydbset<tentity>(basedbset, new proxyqueryable<tentity>((proxydbprovider)proxyqueryable.provider, basedbset.include(path)), manipulator);         }          public override observablecollection<tentity> local         {                         {                 return basedbset.local;             }         }          public override tentity remove(tentity entity)         {             return basedbset.remove(entity);         }          public override ienumerable<tentity> removerange(ienumerable<tentity> entities)         {             return basedbset.removerange(entities);         }          public override dbsqlquery<tentity> sqlquery(string sql, params object[] parameters)         {             return basedbset.sqlquery(sql, parameters);         }          ienumerator<tentity> ienumerable<tentity>.getenumerator()         {             return proxyqueryable.getenumerator();         }          ienumerator ienumerable.getenumerator()         {             return ((ienumerable)proxyqueryable).getenumerator();         }          type iqueryable.elementtype         {             { return proxyqueryable.elementtype; }         }          expression iqueryable.expression         {             { return proxyqueryable.expression; }         }          iqueryprovider iqueryable.provider         {             { return proxyqueryable.provider; }         }          idbasyncenumerator<tentity> idbasyncenumerable<tentity>.getasyncenumerator()         {             return ((idbasyncenumerable<tentity>)proxyqueryable).getasyncenumerator();         }          idbasyncenumerator idbasyncenumerable.getasyncenumerator()         {             return ((idbasyncenumerable)proxyqueryable).getasyncenumerator();         }          public override string tostring()         {             return proxyqueryable.tostring();         }          // note operator isn't virtual! if do:         // dbset<foo> foo = new proxydbset<foo>(...)         // dbset foo2 = (dbset)foo;         // you'll have non-proxed dbset!         public static implicit operator proxydbsetnongeneric<tentity>(proxydbset<tentity> entry)         {             return new proxydbsetnongeneric<tentity>((dbset)entry.basedbset, entry.manipulator);         }     }      public class proxydbprovider : iqueryprovider, idbasyncqueryprovider     {         protected readonly iqueryprovider basequeryprovider;         public readonly func<bool, expression, expression> manipulator;          /// <summary>         ///          /// </summary>         /// <param name="basequeryprovider"></param>         /// <param name="manipulator">first parameter: true execute, false createquery.</param>         public proxydbprovider(iqueryprovider basequeryprovider, func<bool, expression, expression> manipulator)         {             basequeryprovider = basequeryprovider;             manipulator = manipulator;         }          public iqueryable<telement> createquery<telement>(expression expression)         {             expression expression2 = manipulator != null ? manipulator(false, expression) : expression;              iqueryable<telement> query = basequeryprovider.createquery<telement>(expression2);             iqueryprovider provider = query.provider;             proxydbprovider proxy = provider == basequeryprovider ? : new proxydbprovider(provider, manipulator);              return new proxyqueryable<telement>(proxy, query);         }          protected static readonly methodinfo createquerynongenerictogenericmethod = typeof(proxydbprovider).getmethod("createquerynongenerictogeneric", bindingflags.static | bindingflags.nonpublic);          public iqueryable createquery(expression expression)         {             expression expression2 = manipulator != null ? manipulator(false, expression) : expression;              iqueryable query = basequeryprovider.createquery(expression2);             iqueryprovider provider = query.provider;              proxydbprovider proxy = provider == basequeryprovider ? : new proxydbprovider(provider, manipulator);              type entitytype = getiqueryabletypeargument(query.gettype());              if (entitytype == null)             {                 return new proxyqueryable(proxy, query);             }             else             {                 return (iqueryable)createquerynongenerictogenericmethod.makegenericmethod(entitytype).invoke(null, new object[] { proxy, query });             }         }          protected static proxyqueryable<telement> createquerynongenerictogeneric<telement>(proxydbprovider proxy, iqueryable<telement> query)         {             return new proxyqueryable<telement>(proxy, query);         }          public tresult execute<tresult>(expression expression)         {             expression expression2 = manipulator != null ? manipulator(true, expression) : expression;             return basequeryprovider.execute<tresult>(expression2);         }          public object execute(expression expression)         {             expression expression2 = manipulator != null ? manipulator(true, expression) : expression;             return basequeryprovider.execute(expression2);         }          // gets t of iqueryablelt;t&gt;         protected static type getiqueryabletypeargument(type type)         {             ienumerable<type> interfaces = type.isinterface ?                 new[] { type }.concat(type.getinterfaces()) :                 type.getinterfaces();             type argument = (from x in interfaces                              x.isgenerictype                              let gt = x.getgenerictypedefinition()                              gt == typeof(iqueryable<>)                              select x.getgenericarguments()[0]).firstordefault();             return argument;         }          public task<tresult> executeasync<tresult>(expression expression, cancellationtoken cancellationtoken)         {             var asyncqueryprovider = basequeryprovider idbasyncqueryprovider;              if (asyncqueryprovider == null)             {                 throw new notsupportedexception();             }              expression expression2 = manipulator != null ? manipulator(true, expression) : expression;             return asyncqueryprovider.executeasync<tresult>(expression2, cancellationtoken);         }          public task<object> executeasync(expression expression, cancellationtoken cancellationtoken)         {             var asyncqueryprovider = basequeryprovider idbasyncqueryprovider;              if (asyncqueryprovider == null)             {                 throw new notsupportedexception();             }              expression expression2 = manipulator != null ? manipulator(true, expression) : expression;             return asyncqueryprovider.executeasync(expression2, cancellationtoken);         }     }      public class proxyqueryable : iorderedqueryable, iqueryable, ienumerable, idbasyncenumerable     {         protected readonly proxydbprovider proxydbprovider;         protected readonly iqueryable basequeryable;          public proxyqueryable(proxydbprovider proxydbprovider, iqueryable basequeryable)         {             proxydbprovider = proxydbprovider;             basequeryable = basequeryable;         }          public ienumerator getenumerator()         {             return basequeryable.getenumerator();         }          public type elementtype         {             { return basequeryable.elementtype; }         }          public expression expression         {             { return basequeryable.expression; }         }          public iqueryprovider provider         {             { return proxydbprovider; }         }          public override string tostring()         {             return basequeryable.tostring();         }          idbasyncenumerator idbasyncenumerable.getasyncenumerator()         {             var asyncenumerator = basequeryable idbasyncenumerable;              if (asyncenumerator == null)             {                 throw new notsupportedexception();             }              return asyncenumerator.getasyncenumerator();         }     }      public class proxyqueryable<telement> : iorderedqueryable<telement>, iqueryable<telement>, ienumerable<telement>, idbasyncenumerable<telement>, iorderedqueryable, iqueryable, ienumerable, idbasyncenumerable     {         protected readonly proxydbprovider proxydbprovider;         protected readonly iqueryable<telement> basequeryable;          public proxyqueryable(proxydbprovider proxydbprovider, iqueryable<telement> basequeryable)         {             proxydbprovider = proxydbprovider;             basequeryable = basequeryable;         }          public ienumerator<telement> getenumerator()         {             return basequeryable.getenumerator();         }          ienumerator ienumerable.getenumerator()         {             return ((ienumerable)basequeryable).getenumerator();         }          public type elementtype         {             { return basequeryable.elementtype; }         }          public expression expression         {             { return basequeryable.expression; }         }          public iqueryprovider provider         {             { return proxydbprovider; }         }          public override string tostring()         {             return basequeryable.tostring();         }          public idbasyncenumerator<telement> getasyncenumerator()         {             var asyncenumerator = basequeryable idbasyncenumerable<telement>;              if (asyncenumerator == null)             {                 throw new notsupportedexception();             }              return asyncenumerator.getasyncenumerator();         }          idbasyncenumerator idbasyncenumerable.getasyncenumerator()         {             var asyncenumerator = basequeryable idbasyncenumerable;              if (asyncenumerator == null)             {                 throw new notsupportedexception();             }              return asyncenumerator.getasyncenumerator();         }     } } 

an example of manipulator of expressions (this 1 transform .where(x => something) .where(x => && something):

namespace {     using system.linq;     using system.linq.expressions;      public class myexpressionmanipulator : expressionvisitor     {         protected override expression visitmethodcall(methodcallexpression node)         {             if (node.method.declaringtype == typeof(queryable) && node.method.name == "where" && node.arguments.count == 2)             {                 // transforms .where(x => something) in                 // .where(x => && something)                 if (node.arguments[1].nodetype == expressiontype.quote)                 {                     unaryexpression argument1 = (unaryexpression)node.arguments[1]; // expression.quote                      if (argument1.operand.nodetype == expressiontype.lambda)                     {                         lambdaexpression argument1lambda = (lambdaexpression)argument1.operand;                          // important: @ each step you'll reevalute                         // full expression! try not replace twice                         // expression!                         // if have query like:                         // var res = ctx.where(x => true).where(x => true).select(x => 1)                         // first time you'll visit                         //  ctx.where(x => true)                         // , you'll obtain                         //  ctx.where(x => true && true)                         // second time you'll visit                         //  ctx.where(x => true && true).where(x => true)                         // , want obtain                         //  ctx.where(x => true && true).where(x => true && true)                         // , not                         //  ctx.where(x => (true && true) && (true && true)).where(x => true && true)                         if (argument1lambda.body.nodetype != expressiontype.andalso)                         {                             var arguments = new expression[node.arguments.count];                             node.arguments.copyto(arguments, 0);                              arguments[1] = expression.quote(expression.lambda(expression.andalso(argument1lambda.body, argument1lambda.body), argument1lambda.parameters));                             methodcallexpression node2 = expression.call(node.object, node.method, arguments);                             node = node2;                         }                     }                 }             }              return base.visitmethodcall(node);         }     } } 

now... how use it? best way derive context (in case model1) not dbcontext proxydbcontext, this:

public partial class model1 : proxydbcontext {     public model1()         : base("name=model1", manipulate)     {     }      /// <summary>     ///      /// </summary>     /// <param name="executing">true: returned expression executed directly, false: returned expression returned iqueryable&lt&gt.</param>     /// <param name="expression"></param>     /// <returns></returns>     private static expression manipulate(bool executing, expression expression)     {         // see annotation reexecuting same visitor         // multiple times in myexpressionmanipulator().visit .         // executing visitor on executing == true,         // , return expression; on executing == false,         // have guarantee expression won't         // manipulated multiple times.         // written now, expression manipulated         // multiple times.         return new myexpressionmanipulator().visit(expression);     }      // tables     public virtual dbset<parent> parent { get; set; }     public virtual idbset<child> child { get; set; } 

then transparent:

// model1: class model1 : proxydbcontext {} using (var ctx = new model1()) {     // query     var res = ctx.parent.where(x => x.id > 100);     // query automatically manipulated manipulate method } 

another way without subclassing proxydbcontext:

// model1: class model1 : proxydbcontext {} using (var ctx = new model1()) {     func<expression, expression> manipulator = new myexpressionmanipulator().visit;     ctx.parent = new proxydbset<parent>(ctx.parent, manipulator);     ctx.child = new proxydbset<child>(ctx.child, manipulator);      // query     var res = ctx.parent.where(x => x.id > 100); } 

the proxydbcontext<> replaces dbset<>/idbset<> present in context proxydbset<>.

in second example action done explicitly, note taht can create method it, or create factory context (a static method returns context various dbset<> "proxied"), or put proxification in constructor of context (because "original" initialization of dbset<> happens in constructor of dbcontext, , body of constructor of context executed after this), or create multiple subclasses of context, each 1 has constructor proxifies in different way...

note first method (subclassing proxydbcontext<>) "fixes" set<>/set methods otherwise you'll have fix copying code of overloads of these 2 methodsd proxydbcontext<>.


Comments

Popular posts from this blog

android - MPAndroidChart - How to add Annotations or images to the chart -

javascript - Add class to another page attribute using URL id - Jquery -

firefox - Where is 'webgl.osmesalib' parameter? -