c# - How do I Filter one side of a DbJoinExpression -


in ef 6.1 have created defaultexpressionvisitor use idbcommandtreeinterceptor. want know how correctly override dbjoinexpression visitor filter right hand side of join perform same join on filtered set.

based on various approaches (such using bindas etc) errors such as:

  • no property name 'extent2' declared type
  • the referenced variable 'extent2' not defined in current scope.

but cannot mix of comparable types, variables , parameter. little documentation , no example usages of dbjoinexpressions in context.

as example have objectcontext people , animals. , person has association animals own, , pet has ownerid. explicit key relationship between person.id == animal.ownerid.

i have added association, navigation property , called "cats".

so accurate, want filter collection of animals (the right hand expression) using animaltype column discriminator.

    public override dbexpression visit(dbjoinexpression expression)     {        //todo pull these values attributes etc         var discriminatorcolumn = "animaltype";         var discriminatortype = "cat";          //people         dbexpressionbinding left = this.visitexpressionbinding(expression.left);         //unfiltered animals         dbexpressionbinding right = this.visitexpressionbinding(expression.right);           //todo filter right side using animaltype dbcolumn , re-join         // right hand collection element         var entitysetexpression = right.expression dbscanexpression;          var variablereference = right.variable;          // create property based on variable in order apply equality         var discriminatorproperty = dbexpressionbuilder.property(variablereference, discriminatorcolumn);         var predicateexpression = dbexpressionbuilder.equal(discriminatorproperty, dbexpression.fromstring(discriminatortype));          //filtered animals being cats         var filterexpression = dbexpressionbuilder.filter(entitysetexpression.bind(),predicateexpression);           var joincondition = this.visitexpression(expression.joincondition) dbcomparisonexpression;         dbexpressionbinding filteredright = filterexpression.bind();          dbexpression newexpression = expression;         if (!referenceequals(expression.left, left)             || !referenceequals(expression.right, filteredright)             || !referenceequals(expression.joincondition, joincondition))         {             if (dbexpressionkind.innerjoin == expression.expressionkind)             {                 newexpression = dbexpressionbuilder.innerjoin(left, filteredright, joincondition);             }             else if (dbexpressionkind.leftouterjoin == expression.expressionkind)             {                 newexpression = dbexpressionbuilder.leftouterjoin(left, filteredright, joincondition);             }             else             {                 debug.assert(                     expression.expressionkind == dbexpressionkind.fullouterjoin,                     "dbjoinexpression had expressionkind other innerjoin, leftouterjoin or fullouterjoin?");                 newexpression = dbexpressionbuilder.fullouterjoin(left, filteredright, joincondition);             }         }          return newexpression;     } 

essentially looking create sql join filter like:

select .... people p left join      animals on p.id = a.ownerid (here ***and a.animaltype = 'cat'***) ( or here ***a.animaltype = 'cat'***) 

reading source code on codeplex defaultexpressionvisitor pushing scope variables method private. might explain parameter scope issues seeing.

any appreciated.

turns out simpler thought. avoided trying filter dbscanexpression , added condition join andexpression

    public override dbexpression visit(dbjoinexpression expression)     {         //todo pull these values attributes etc         var discriminatorcolumn = "animaltype";         var discriminatortype = "cat";         //if (attribute.getcustomattributes())          //people         dbexpressionbinding left = this.visitexpressionbinding(expression.left);         //unfiltered animals         dbexpressionbinding right = this.visitexpressionbinding(expression.right);            // create property based on variable in order apply equality         var discriminatorproperty = dbexpressionbuilder.property(right.variable, discriminatorcolumn);          //todo create type discriminatortype match property type eg string, guid, int etc         var predicateexpression = dbexpressionbuilder.equal(discriminatorproperty, dbexpression.fromstring(discriminatortype));          //use existing condition , combine new condition using ,         var joincondition = dbexpressionbuilder.and(expression.joincondition, predicateexpression);            dbexpression newexpression = expression;          //only re-create join if changed         if (!referenceequals(expression.left, left)             || !referenceequals(expression.right, right)             || !referenceequals(expression.joincondition, joincondition))         {             switch (expression.expressionkind)             {                 case dbexpressionkind.innerjoin:                     newexpression = dbexpressionbuilder.innerjoin(left, right, joincondition);                     break;                 case dbexpressionkind.leftouterjoin:                     newexpression = dbexpressionbuilder.leftouterjoin(left, right, joincondition);                     break;                 default:                     debug.assert(                         expression.expressionkind == dbexpressionkind.fullouterjoin,                         "dbjoinexpression had expressionkind other innerjoin, leftouterjoin or fullouterjoin?");                     newexpression = dbexpressionbuilder.fullouterjoin(left, right, joincondition);                     break;             }         }          return newexpression;     } 

Comments

Popular posts from this blog

javascript - AngularJS custom datepicker directive -

javascript - jQuery date picker - Disable dates after the selection from the first date picker -