नोट: यह मेरे पास कुछ ऐसा है जो इसे बॉक्स से बाहर नहीं कर सकता है। लेकिन यह एक अच्छा प्रारंभिक बिंदु होगा।
public static IQueryable<TEntity> Where<TEntity>(this IQueryable<TEntity> source,
IEnumerable<WhereSpecifier> orClauses)
where TEntity : class
{
if (!orClauses.Any()) return source.Where(t => false);
Type type = typeof (TEntity);
ParameterExpression parameter = null;
Expression predicate = Expression.Constant(false, typeof (bool));
ParameterExpression whereEnt = Expression.Parameter(type, "WhereEnt");
foreach (WhereSpecifier orClause in orClauses)
{
Expression selector;
if (orClause.Selector != null)
{
selector = orClause.Selector;
parameter = orClause.Parameter;
}
else
{
parameter = whereEnt;
Type selectorResultType;
selector = GenerateSelector<TEntity>(parameter, orClause.Column, out selectorResultType);
}
Expression clause = selector.CallMethod(orClause.Method,
MakeConstant(selector.Type, orClause.Value), orClause.Modifiers);
predicate = Expression.Or(predicate, clause);
}
var lambda = Expression.Lambda(predicate, whereEnt);
var resultExp = Expression.Call(typeof (Queryable), "Where", new[] {type},
source.Expression, Expression.Quote(lambda));
return source.Provider.CreateQuery<TEntity>(resultExp);
}
GenerateSelector:
public static Expression GenerateSelector<TEntity>(ParameterExpression parameter, string propertyName,
out Type resultType) where TEntity : class
{
// create the selector part, but support child properties
PropertyInfo property;
Expression propertyAccess;
if (propertyName.Contains('.'))
{
// support to be sorted on child fields.
String[] childProperties = propertyName.Split('.');
property = typeof (TEntity).GetProperty(childProperties[0]);
propertyAccess = Expression.MakeMemberAccess(parameter, property);
for (int i = 1; i < childProperties.Length; i++)
{
property = property.PropertyType.GetProperty(childProperties[i]);
propertyAccess = Expression.MakeMemberAccess(propertyAccess, property);
}
}
else
{
property = typeof (TEntity).GetProperty(propertyName);
propertyAccess = Expression.MakeMemberAccess(parameter, property);
}
resultType = property.PropertyType;
return propertyAccess;
}
WHereSpecifier:
public class WhereSpecifier
{
public WhereSpecifier(string column, CheckMethod method, string value, CheckMethodModifiers modifiers)
{
Modifiers = modifiers;
Value = value;
Column = column;
Method = method;
}
public WhereSpecifier(string column, CheckMethod method, string value)
: this(column, method, value, CheckMethodModifiers.None)
{
}
public Expression Selector { get; set; }
public ParameterExpression Parameter { get; set; }
public string Column { get; set; }
public CheckMethod Method { get; set; }
public CheckMethodModifiers Modifiers { get; set; }
public string Value { get; set; }
}
उपयोग:
var column = typeof(TEntity).Name + "ID";
var where = from id in SelectedIds
select new WhereSpecifier(column, CheckMethod.Equal, id.ToString());
return GetTable().Where(where);
सैयद मेहरोज आलम द्वारा इस ब्लॉग पोस्ट में कई उदाहरण हैं जो बहुत अच्छी तरह से हैं, और यह दिखाता है कि कैसे LINQ क्वेरी सिंटैक्स को विधि सिंटैक्स के साथ उपयोगी तरीके से जोड़ना है: [LINQ: स्थगित निष्पादन और अनाम प्रकारों का उपयोग करने वाले जटिल प्रश्नों को कैसे बनाएं] (http://smehrozalam.wordpress.com/2010/04/06/linq-how-to-build-complex-queries-utilizing-deferred-execution-and-anonymous-types/) –