I'm basically trying to construct a query, and I don't know why microsoft made this so difficult in Entity Framework and LINQ. I have various parameter STRINGS. So if you see a variable, assume it's a string passed in from somewhere.
users = this.entities.tableUsers
.Where(searchfield+" LIKE %#0%", search)
.OrderBy(x => x.GetType().GetProperty(order_by).GetValue(x, null).ToString())
.Skip(Convert.ToInt32(limit_begin))
.Take(Convert.ToInt32(limit_end))
.ToList();
My question is what to put inside "Where()" function in LINQ.
I want to search a field with string "searchfield", for the value .contains() "search".
Not sure why Visual Studio won't let me do this easily.
I've tried this as well, no luck:
.Where(x => x.GetType().GetProperty(searchfield).GetValue(x, null).ToList().Contains(search))
Note: I don't want to install any new libraries, this should be incredibly easy and simple for a modern language. I don't mind if the query returns all the rows and I search through it AFTER with .Contains().
This is not trivial, but I believe it can be done. The following has not been tested. The code is borrowed from here.
Create a helper method somewhere like
public static Expression<Func<T, bool>> GetContainsExpression<T>(string propertyName, string containsValue)
{
var parameterExp = Expression.Parameter(typeof(T), "type");
var propertyExp = Expression.Property(parameterExp, propertyName);
MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
var someValue = Expression.Constant(propertyValue, typeof(string));
var containsMethodExp = Expression.Call(propertyExp, method, someValue);
return Expression.Lambda<Func<T, bool>>(containsMethodExp, parameterExp);
}
public static Expression<Func<T, TKey>> GetPropertyExpression<T, TKey>(string propertyName)
{
var parameterExp = Expression.Parameter(typeof(T), "type");
var exp = Expression.Property(parameterExp, propertyName);
return Expression.Lambda<Func<T, TKey>>(exp, parameterExp);
}
Use it like
users = this.entities.tableUsers
.Where(GetContainsExpression<User>(searchfield, search))
.OrderBy(GetPropertyExpression<User, string>(searchfield))
...
UPDATE
As an alternative, you could create extension methods to provide a cleaner syntax. Create the following methods in a static class somewhere:
public static IQueryable<T> WhereStringContains<T>(this IQueryable<T> query, string propertyName, string contains)
{
var parameter = Expression.Parameter(typeof(T), "type");
var propertyExpression = Expression.Property(parameter, propertyName);
MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
var someValue = Expression.Constant(contains, typeof(string));
var containsExpression = Expression.Call(propertyExpression, method, someValue);
return query.Where(Expression.Lambda<Func<T, bool>>(containsExpression, parameter));
}
public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> query, string propertyName)
{
var propertyType = typeof(T).GetProperty(propertyName).PropertyType;
var parameter = Expression.Parameter(typeof(T), "type");
var propertyExpression = Expression.Property(parameter, propertyName);
var lambda = Expression.Lambda(propertyExpression, new[] { parameter });
return typeof(Queryable).GetMethods()
.Where(m => m.Name == "OrderBy" && m.GetParameters().Length == 2)
.Single()
.MakeGenericMethod(new[] { typeof(T), propertyType })
.Invoke(null, new object[] { query, lambda }) as IOrderedQueryable<T>;
}
public static IOrderedQueryable<T> OrderByDescending<T>(this IQueryable<T> query, string propertyName)
{
var propertyType = typeof(T).GetProperty(propertyName).PropertyType;
var parameter = Expression.Parameter(typeof(T), "type");
var propertyExpression = Expression.Property(parameter, propertyName);
var lambda = Expression.Lambda(propertyExpression, new[] { parameter });
return typeof(Queryable).GetMethods()
.Where(m => m.Name == "OrderByDescending" && m.GetParameters().Length == 2)
.Single()
.MakeGenericMethod(new[] { typeof(T), propertyType })
.Invoke(null, new object[] { query, lambda }) as IOrderedQueryable<T>;
}
Then you can call them like:
var users = this.entities.tableUsers.WhereStringContains(searchField, search)
.OrderBy(searchField);
this should be incredibly easy and simple for a modern language
No, it should not if it goes against that language paradigm. LINQ and Entity Framework (as well as any other decent ORM out there) are made precisely to avoid what you're trying to accomplish: non-typed and non-compiler-verifiable queries. So basically you're forcing square peg into round hole.
You can still take a look at Dynamic LINQ.
You'll have to build an expression tree to pass to the Where method. Here's a loose adaptation of some code I have lying about:
string searchfield, value; // Your inputs
var param = Expression.Parameter(typeof(User), "user");
return Expression.Lambda<Func<T, bool>>(
Expression.Call(
Expression.Property(
param,
typeof(User).GetProperty(searchfield)),
typeof(string).GetMethod("Contains"),
Expression.Constant(value)),
param);
That will generate an appropriate expression to use as the parameter to Where.
EDIT: FYI, the resultant expression will look something like user => user.Foo.Contains(bar).
EDIT: To sort, something like this (ripped from my DynamicOrderList class):
private IQueryable<T> OrderQuery<T>(IQueryable<T> query, OrderParameter orderBy)
{
string orderMethodName = orderBy.Direction == SortDirection.Ascending ? "OrderBy" : "OrderByDescending";
Type t = typeof(T);
var param = Expression.Parameter(t, "user");
var property = t.GetProperty(orderBy.Attribute);
return query.Provider.CreateQuery<T>(
Expression.Call(
typeof(Queryable),
orderMethodName,
new Type[] { t, typeof(string) },
query.Expression,
Expression.Quote(
Expression.Lambda(
Expression.Property(param, property),
param))
));
}
My answer to your other question about this:
When creating dynamic linq sorting and searching order statements in Entity Framework
Related
I'm writing an extension method that takes a property name as a string and builds an expression tree to order by that column. It needs to support Linq-to-Entities as I'd like the order-by operation to be done in SQL. The method currently works as intended, however I'd now like to prioritise non-null values, i.e. always leave null values at the end of the collection, regardless of the order direction.
Here's the method I have so far:
public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source, string orderBy, bool ascending) {
Type type = typeof(T);
ParameterExpression parameter = Expression.Parameter(type, "p");
PropertyInfo property = type.GetProperty(orderBy);
if (property == null) {
throw new ArgumentException("The given value did not match any available properties.", nameof(orderBy));
}
// Get the property accessor p.SortColumn
Expression propertyAccess = Expression.MakeMemberAccess(parameter, property);
// Get the lambda expression p => p.SortColumn
LambdaExpression orderByExp = Expression.Lambda(propertyAccess, parameter);
// Call the OrderBy(Descending) method with the above lambda expression
MethodCallExpression resultExp = Expression.Call(typeof(Queryable),
ascending ? "OrderBy" : "OrderByDescending", new[] { type, property.PropertyType },
source.Expression, Expression.Quote(orderByExp));
return (IOrderedQueryable<T>)source.Provider.CreateQuery<T>(resultExp);
}
If I didn't need to support Linq-to-Entities, I'd write something like this:
source.OrderBy(x => property.GetValue(x) == null).ThenBy/Descending(x => property.GetValue(x));
However, the Expression.Call()... syntax has thrown me as I don't fully understand what's happening behind the scenes there.
How would I go about prepending an OrderBy(value == null) operation to the expression tree?
Just order by equal to null first
var result = list.OrderBy(x => x.Name == null).ThenBy(x => x.Name)
Example
public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source, string propertyName, bool ascending)
{
var propertyInfo = typeof(T).GetProperty(propertyName) ?? throw new ArgumentException("The given value did not match any available properties.", nameof(propertyName));
var parameterExpression = Expression.Parameter(typeof(T), "p");
var propertyAccess = Expression.MakeMemberAccess(parameterExpression, propertyInfo);
var orderByNullLambda = Expression.Lambda(
Expression.Equal(propertyAccess, Expression.Constant(null)),
parameterExpression);
var resultExp = Expression.Call(
typeof(Queryable),
ascending ? "OrderBy" : "OrderByDescending",
new[] {typeof(T), typeof(bool)},
source.Expression,
Expression.Quote(orderByNullLambda));
var orderByPropertyLambda = Expression.Lambda(
propertyAccess,
parameterExpression);
var resultExp2 = Expression.Call(
typeof(Queryable),
ascending ? "ThenBy" : "ThenByDescending",
new[] {typeof(T), propertyInfo.PropertyType},
resultExp,
Expression.Quote(orderByPropertyLambda));
return (IOrderedQueryable<T>) source.Provider.CreateQuery<T>(resultExp2);
}
Usage
var list = new List<Bob>()
{
new() {Name = "Bsd"},
new() {Name = null},
new() {Name = "asd"}
};
var result = list.AsQueryable().OrderBy("Name", true).ToList();
foreach (var item in result)
Console.WriteLine(item.Name ?? "Null");
Result
asd
Bsd
Null
I have a service method called FindAll() that expects a expression/predicate parameter and returns all the matching rows.
Let's say I have a collection of Book objects and I want to get all the books with their names found in a list of strings. I'd have something like this:
var lstNames = { "Book1", "Book2" };
var matchedBooks = myService<Book>.FindAll(x => lstNames.Any(y => x.Name.Equals(y)));
I also have a number of other classes that all have the Name property so I'd like to build a dynamic expression which allows me to do something like:
var matchedObjs = myService<T>.FindAll(x => lstNames.Any(y => x.Name.Equals(y)));
How do I build such a dynamic expression?
Thanks to this answer: How to declare a Linq Expression variable in order to have it processed as a dbParameter
I propose you do this:
static Expression<Func<T, bool>> GetExpr<T> (string name, string value)
{
ParameterExpression param = Expression.Parameter(typeof(T), "x");
Expression prop = Expression.Property(param, name); // this is the property name, e.g. .Name
Expression<Func<string>> valueLambda = () => value; // This is the value for == expression.
Expression lookupExpression = Expression.Equal(prop, valueLambda.Body);
Expression<Func<T, bool>> expr = Expression.Lambda<Func<T, bool>>(lookupExpression, param);
return expr;
}
... or, for .Contains():
static Expression<Func<T, bool>> GetExprContains<T>(string name, string[] value)
{
ParameterExpression param = Expression.Parameter(typeof(T), "x");
Expression prop = Expression.Property(param, name); // this is the property name, e.g. .Name
Expression<Func<string[]>> valueLambda = () => value; // This is the value for .Contains() expression.
var mi =
typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public)
.FirstOrDefault(x => x.Name == "Contains" && x.GetParameters().Count() == 2)
.MakeGenericMethod(typeof(string)); // Need methodinfo for .Contains(), might want to keep static somewhere
var lookupExpr = Expression.Call(null, mi, valueLambda.Body, prop);
Expression<Func<T, bool>> expr = Expression.Lambda<Func<T, bool>>(lookupExpr, param);
return expr;
}
Tested, works with EF.
I'm creating a method that receives a Queryable<T> source, a string with a property name/path (could be a deep property for example "TrParent.DataTypes" to achieve this x => x.TrParent.DataTypes) and Enumerable<int> which holds the values I need to intersect.
Basically I come from the need to create the following query dynamically (I mean <DT_Det_Tr> and TrParent.DataTypes being know only at runtime, in the example DT_Det_Tr is not a type it is a class):
var _vals = new List<int>();
var res = dbContext.Set<DT_Det_Tr>()
.Where
(x => x.TrParent.DataTypes
.Select(t => t.Id)
.Intersect(_vals)
.Any()
);
Please keep in mind that the preceding query is just an example of what I need to achieve dynamically, what I really need is an expression tree that creates a predicate like the one shown above but using a dynamic type and with the deep navigation property specified within a string.
So, I'm using this function to create the expression for the deep property:
private static LambdaExpression CreateDelegateExpression<T>(out Type resultingtype, string property, string parameterName = "x")
{
var type = typeof(T);
ParameterExpression param = Expression.Parameter(type, parameterName);
Expression expr = param;
foreach (string prop in property.Split('.'))
{
PropertyInfo pi = type.GetProperty(prop);
expr = Expression.Property(expr, pi);
type = pi.PropertyType;
}
Type delegateType = typeof(Func<,>).MakeGenericType(typeof(T), type);
LambdaExpression lambda = Expression.Lambda(delegateType, expr, param);
resultingtype = type;
return lambda;
}
And here is what I have so far for my function:
public static IQueryable<T> Intersect<T>(this IQueryable<T> source, string property, IEnumerable<int> value)
{
//List of ids
var _value = Expression.Constant(value);
//Get delegate expression to the deep property and it's inner type
Type type = null;
var lambda = CreateDelegateExpression<T>(out type, property, "x");
var enumtype = type.GetGenericArguments()[0];
ParameterExpression tpe = Expression.Parameter(enumtype, "y");
Expression propExp = Expression.Property(tpe, enumtype.GetProperty("Id"));
MethodInfo innermethod = typeof(Queryable).GetMethods().Where(x => x.Name == "Select").First();
//Error on next line...
var selectCall = Expression.Call(typeof(Queryable),
"Select",
new Type[] { enumtype, typeof(long) },
lambda,
propExp);
//TODO: Add rest of logic and actually filter the source
return source;
}
In the var selectCall = line I'm getting error:
No generic method 'Select' on type 'System.Linq.Queryable' is compatible with the supplied type arguments and arguments. No type arguments should be provided if the method is non-generic.
I've read a lot here on SO and other sites but I can't get past this part, I feel I'm going to bump into more trouble when I get to the .Intersect(List<int>).Any() part so any help on that also would be grand, thanks.
After a lot of thought, investigation and attempts I came up with a solution.
First, I made a simpler version of my goal query (the static example I used in my question), so instead of:
var res = dbContext.Set<DT_Det_Tr>()
.Where
(x => x.TrParent.DataTypes
.Select(t => t.Id)
.Intersect(_vals)
.Any()
);
I made this:
var res = dbContext.Set<DT_Det_Tr>()
.Where
(x => x.TrParent.DataTypes
.Any(y => _vals.Contains(y.Id))
);
Which is a lot easier to translate to expressions (or at least it was for me) because it omits the Select call.
I got rid of the method I was using to create the deep navigation property expression and streamlined it in my Intersect function, this was because it was doing some work I don't really need here plus I needed access to some of the variables I use inside it, then I made this:
public static IQueryable<T> Intersect<T>(this IQueryable<T> source, string property, IEnumerable<int> value)
{
var type = typeof(T);
var _value = Expression.Constant(value); //List of ids
//Declare parameter for outer lambda
ParameterExpression param = Expression.Parameter(type, "x");
//Outer Lambda
Expression expr = param;
foreach (string prop in property.Split('.')) //Dig for deep property
{
PropertyInfo pi = type.GetProperty(prop);
expr = Expression.Property(expr, pi);
type = pi.PropertyType;
}
//Get deep property's type
var enumtype = type.GetGenericArguments()[0];
//Declare parameter for inner lambda
ParameterExpression tpe = Expression.Parameter(enumtype, "y");
//Inner Collection lambda logic
//Property for inner lambda
Expression propExp = Expression.Property(tpe, enumtype.GetProperty("Id"));
//Contains method call .Contains(y.Id)
var containsMethodExp = Expression.Call(typeof(Enumerable), "Contains", new[] { propExp.Type }, _value, propExp);
//Create Expression<Func<enumtype, bool>>
var innerDelegateType = typeof(Func<,>).MakeGenericType(enumtype, typeof(bool));
//Create Inner lambda y => _vals.Contains(y.Id)
var innerFunction = Expression.Lambda(innerDelegateType, containsMethodExp, tpe);
//Get Any method info
var anyMethod = typeof(Enumerable).GetMethods().Where(m => m.Name == "Any" && m.GetParameters().Length == 2).Single().MakeGenericMethod(enumtype);
//Call Any with inner function .Any(y => _vals.Contains(y.Id))
var outerFunction = Expression.Call(anyMethod, expr, innerFunction);
//Call Where
MethodCallExpression whereCallExpression = Expression.Call
(
typeof(Queryable),
"Where",
new Type[] { source.ElementType },
source.Expression,
Expression.Lambda<Func<T, bool>>(outerFunction, new ParameterExpression[] { param })
);
//Create and return query
return source.Provider.CreateQuery<T>(whereCallExpression);
}
I hope this helps anyone trying to develop a similar solution.
Working with expression trees can be very hard and frustrating at first, but it's a really powerful tool once you get the hold of it.
If you have access to the dynamic keyword from c# 4.0, you might be able to work around the problem like this:
var _vals = new List<int>();
var res = dbContext.Set<DT_Det_Tr>()
.Where(obj => { dynamic x = obj;
return x.TrParent.DataTypes
.Select(t => t.Id)
.Intersect(_vals)
.Any();
}
);
But I don't know enough about the details of the problem you want to solve to say for sure.
I want to use Dynamic LINQ Query to Search with some text in all Properties in a class. i am using following function to create expression. I am passing property name and search text to the method.
In that method if the property type is String then it is working fine. if the property type is int, DateTime, GUID. then it is not working.
As we know Contains method only for array of elements or for string. I am thinking the value to property should type cast to string. So How to do it? Solution with Explanation is help full.
i Collected code from this.
public static Expression<Func<T, bool>> ContainsExp<T>(string propertyName, string contains)
{
var parameterExp = Expression.Parameter(typeof(T), "type");
var propertyExp = Expression.Property(parameterExp, propertyName);
MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
var someValue = Expression.Constant(contains, typeof(string));
var containsMethodExp = Expression.Call(propertyExp, method, someValue);
return Expression.Lambda<Func<T, bool>>(containsMethodExp, parameterExp);
}
Well, you probably know that's it's not possible to use ToString() in linq to entities.
So the following question is : how can I convert other types to string.
For numeric values, you have SqlFunctions.StringConvert, but it has only overloads for double? and decimal?
For DateTime, you may find something using SqlFunctions.StringConvert after having applied SqlFunctions.DatePart on your DateTime (which probably means at least 3 call to SqlFunctions.DatePart, for year, month, day)
For Guid, I don't think there's a way to do it directly. One way (at db level, if you use Sql Server) could be to have a Computed column. The computed column could store a varchar converted representation of your GUID. Maybe there's a better way.
Anyway, here's at least a sample which should work for integer as well as string:
public static Expression<Func<T, bool>> ContainsExp<T>(string propertyName, string contains)
{
//first, get the type of your property
var propertyType = typeof(T).GetProperty(propertyName).PropertyType;
//no change
var parameterExp = Expression.Parameter(typeof (T), "type");
Expression propertyExp = Expression.Property(parameterExp, propertyName);
//if property's type is int
if (propertyType == typeof (int))
{
//convert your Expression to a nullable double (or nullable decimal),
//so that you can use SqlFunctions.StringConvert
propertyExp = Expression.Convert(propertyExp, typeof (double?));
//get the SqlFunctions.StringConvert method for nullable double
var stringConvertMethod = typeof (SqlFunctions).GetMethod("StringConvert", new[] {typeof (double?)});
//call StringConvert on your converted expression
propertyExp = Expression.Call(stringConvertMethod , propertyExp);
}
//no change
var method = typeof (string).GetMethod("Contains", new[] {typeof (string)});
var someValue = Expression.Constant(contains, typeof (string));
var containsMethodExp = Expression.Call(propertyExp, method, someValue);
return Expression.Lambda<Func<T, bool>>(containsMethodExp, parameterExp);
}
public static IQueryable<T> FieldsContains<T>(this IQueryable<T> query, List<string> fileds, string searchValue)
{
Expression predicate = null;
var parameterExpression = Expression.Parameter(typeof(T), "type");
foreach (string field in fileds)
{
var next = GetFieldContainsExpression<T>(parameterExpression, field, searchValue);
if (predicate == null)
{
predicate = next;
}
else
{
predicate = Expression.Or(predicate, next);
}
}
var lambda = Expression.Lambda<Func<T, bool>>(predicate, parameterExpression);
return query.Where(lambda);
}
private static Expression GetFieldContainsExpression<T>(ParameterExpression parameterExpression, string field, string value)
{
var propertyType = typeof(T).GetProperty(field).PropertyType;
Expression propertyExpression = Expression.Property(parameterExpression, field);
var filterValue = Expression.Constant(value);
var method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
//call toString first to ignore type errors(datetime, int ...)
var toStringExpression = Expression.Call(propertyExpression, "ToString", Type.EmptyTypes);
var containsExpression = Expression.Call(toStringExpression, method, filterValue);
return containsExpression;
}
T is a type that may or may not have a specific property, lets say 'City'. For the types that have a property named 'City', I would like to restrict the records such that only residents of the Gotham are returned and they are sorted.
public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, string ordering, params object[] values)
{
var type = typeof(T);
var property = type.GetProperty(ordering);
var parameter = Expression.Parameter(type, "p");
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
var orderByExp = Expression.Lambda(propertyAccess, parameter);
MethodCallExpression resultExp = Expression.Call(
typeof(Queryable),
"OrderBy",
new Type[] { type, property.PropertyType },
source.Expression,
Expression.Quote(orderByExp));
string propertyToRestrictOn = "City";
string restrictedValue = "Gotham";
var restrictedProperty = type.GetProperty(propertyToRestrictOn);
if(null ! = restrictedProperty )
{
// TODO: What to add here so than only those records are returned that have a
// property named City and the value is 'Gotham'???
}
return source.Provider.CreateQuery<T>(resultExp);
}
if possible please name/link some helpful literature here as well just in case I have to create more complex queries i.e. mix And/OR
The code was borrowed from
How do I apply OrderBy on an IQueryable using a string column name within a generic extension method?
I'm not quite sure if I have understood you correctly, but I think I was in the same situation a few months ago.
The posted code here was my solution.
I think you should be especially interested in line 24.
Edit:
PropertyInfo p = ... // I used reflection in my examply to get properties with a certain Attribute
var expressionParameter = Expression.Parameter(typeof(SomeClass), "lambda");
var parameter = new [] { expressionParameter };
var propertyAccess = Expression.Property(expressionParameter, p);
var nullCheck = Expression.NotEqual(propertyAccess, Expression.Constant(null, p.PropertyType));
var nullCheckLambda = Expression.Lambda<Func<SomeClass, Boolean>>(nullCheck, parameter);
var containsMethodInfo = typeof(String).GetMethod("Contains", new[] { typeof(String) });
var contains = Expression.Call(propertyAccess, containsMethodInfo, Expression.Constant("ell"));
var containsLambda = Expression.Lambda<Func<SomeClass, Boolean>>(contains, new[] { expressionParameter });
var predicate = Expression.Lambda<Func<SomeClass, Boolean>>(
// line 24
Expression.AndAlso(nullCheckLambda.Body, containsLambda.Body), parameter);
Console.WriteLine(predicate.ToString());
I think you're making this harder than you have to. In the first part of your code (the OrderBy()), you don't actually need to generate the whole query expression, just the lambda inside it.
And in the second part (the optional Where()) you can do pretty much the same thing, just add Expression.Equal() and Expression.Constant():
public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, string ordering)
{
var type = typeof(T);
var property = type.GetProperty(ordering);
var parameter = Expression.Parameter(type, "p");
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
// necessary for value types to work
var cast = Expression.Convert(propertyAccess, typeof(object));
var orderByExp = Expression.Lambda<Func<T, object>>(cast, parameter);
IQueryable<T> result = source.OrderBy(orderByExp);
string propertyToRestrictOn = "City";
string restrictedValue = "Gotham";
var restrictedProperty = type.GetProperty(propertyToRestrictOn);
if (restrictedProperty != null)
{
var restrictionParameter = Expression.Parameter(type, "p");
var restrictionPropertyAccess =
Expression.MakeMemberAccess(restrictionParameter, restrictedProperty);
var restrictionEquality =
Expression.Equal(restrictionPropertyAccess,
Expression.Constant(restrictedValue));
var whereExp =
Expression.Lambda<Func<T, bool>>(restrictionEquality, restrictionParameter);
result = result.Where(whereExp);
}
return result;
}
Also, if your method is going to do more than just ordering, I think you shouldn't call it OrderBy().
You're half-way there already. You have the ordered expression already, so you're just going to use the Queryable.OrderBy expression call in a Queryable.Where expression (or vice-versa, doesn't really matter).
if(null != restrictedProperty )
{
var notEqualExp = Expression.NotEqual(parameter,
Expression.Constant(restrictedValue, typeof(string)));
resultExp = Expression.Call(
typeof(Queryable),
"Where",
new Type[] { type },
resultExp,
Expression.Lambda(notEqualExp, parameter));
}
Haven't worked with building Expressions by hand in a while, so this is purely being done from memory. However, it should at least get you started and give you something to work with.
P.S. I would actually perform this check BEFORE the OrderBy method call. That way you end up with Queryably.Where(...).OrderBy(...) instead. But I guess if this is getting translated by the provider anyway, then shouldn't matter. However, just something I'd do to reduce any ambiguity of the generated query.