score:6

Accepted answer

following some other links , i found a couple of options. one would be to dynamically create the expression tree which became a quagmire rather quickly, the other is to build the $filter manually. however and add it with .addqueryoption() . however if there are already other where clauses in the query this breaks since the resulting url now has two $filter entries.. so what i do is take my original query, and then grab the url and the querystring and grab the $filter , and then if it exists add my own dynamic stuff and run a new query. here is a demo (running in linqpad)

//grab original query as a dataservicequery
dataservicequery<networkdevice> originalquery = (dataservicequery<networkdevice>) 
    (from x in networkdevices
    where   
    x.type == "switch"
    select x);
//get the http querystring
var querystr = (originalquery).requesturi.query;
var filter = system.web.httputility.parsequerystring(querystr)["$filter"];

/* create our own dynamic filter equivilant to 
    x.name == "x" ||
    x.name == "y" 
*/
string[] names = { "device1", "device2" };
stringbuilder sb = new stringbuilder();
sb.append("(");
foreach (string s in names)
{
    sb.append(string.format("name eq '{0}'",s));
    sb.append(" or ");
}
sb.remove(sb.length - 4, 4);
sb.append(")");
var dynamicfilter = sb.tostring();
// if there was an original filter we'll add the dynamic one with and , otherwise we'll just use the dynamicone
var newfilter = dynamicfilter;
if ( filter != null && filter.trim() != string.empty )
{
newfilter = filter + " and " + newfilter;
}
newfilter.dump();


var finalquery = 
    (from x in networkdevices.addqueryoption("$filter",newfilter)
    select x).take(50);

finalquery.dump();

score:0

here's an example of an expressionvistor which i used to convert a contains into an orelse:

    public class wherecontainstreemodifier : expressionvisitor
    {
        private expression translatecontains(lambdaexpression lambda)
        {
            var methodcall = lambda.body as methodcallexpression;
            var member = methodcall.object as memberexpression;
            var objectmember = expression.convert(member, typeof(object));
            var getterlambda = expression.lambda<func<object>>(objectmember);
            var getter = getterlambda.compile();

            var list = (ienumerable)getter();

            expression result = null;
            foreach (object item in list)
            {
                var equal = expression.equal(methodcall.arguments[0], expression.constant(item));
                if (result == null)
                    result = equal;
                else
                    result = expression.orelse(result, equal);
            }

            result = expression.lambda(lambda.type, result, lambda.parameters);
            return result;
        }

        protected override expression visitlambda<t>(expression<t> node)
        {
            if ((node.body as methodcallexpression).method.name == "contains")
                return translatecontains(node);
            else
                return node;
        }
    }

Related Query

More Query from same tag