У меня есть приложение, в котором все запросы создаются динамически на основе простого сообщения данных, полученного службой WCF.Сообщение данных, проще говоря, представляет собой набор пар имя столбца / значение столбца с добавлением оператора, например, Equals, Less Than и т. Д.
Простое сообщение данных для ColumnName-Value-Operator
Name, Joe, Equals
Age, 35, Less Than
Occupation, Geek, Equals
Rate, 1000, Greater Than
и т.д ...
Я несколько успешно использовал динамические двоичные выражения, основанные на содержимом сообщения данных.
BinaryExpression expression = null;
ParameterExpression parameter = Expression.Parameter(typeof(MessageType), "p");
foreach (row in DataMessage)
{
BinaryExpression exp = DataLib.MakeQueryFilter(typeof(MessageType),
row.ColumnName,row.ColumnValue,column.DataOperator.ToString(), parameter);
expression = expression == null ? exp : Expression.AndAlso(expression, exp);
results = DataContext.MessageType.Where(Expression.Lambda<Func<Media, bool>>(expression, parameter));
}
public static BinaryExpression MakeQueryFilter(Type type, string propertyName, object value, string dataoperator, ParameterExpression parameter)
{
//var type = oType.GetType();
object queryvalue = null;
var property = type.GetProperty(propertyName);
Type propertyType = property.PropertyType;
if ((propertyType.IsGenericType) && (propertyType.GetGenericTypeDefinition() == typeof(Nullable)))
propertyType = propertyType.GetGenericArguments()[0];
// convert the value appropriately
if (propertyType == typeof(System.Int32))
queryvalue = Convert.ToInt32(value);
if (property.PropertyType == typeof(DateTime))
queryvalue = Convert.ToDateTime(value);
if (property.PropertyType == typeof(Double))
queryvalue = Convert.ToDouble(value);
if (property.PropertyType == typeof(String))
queryvalue = Convert.ToString(value);
if (property.PropertyType == typeof(Guid))
queryvalue = new Guid(value.ToString());
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
var constantValue = Expression.Constant(queryvalue);
Type[] types = new Type[2];
types.SetValue(typeof(Expression), 0);
types.SetValue(typeof(Expression), 1);
var methodInfo = typeof(Expression).GetMethod(dataoperator, types);
var equality2 = (BinaryExpression)methodInfo.Invoke(null, new object[] { propertyAccess, constantValue });
return equality2;
}
Проблема, с которой я сталкиваюсь, - это когда яхотите запросить отношение к значению в другой таблице и даже углубиться в две> n-ые связи.Примерно так:
Name, Joe, Equals
Age, 35, Less Than
Jobs.Occupation, Geek, Equals
Jobs.Occupation.Salary.Rate, 1000, Greater Than
У меня нет проблем с написанием запроса LINQ вручную:
var results = from m in DataContext.MessageType
where m.Name == "Joe"
& m.Age == 35
& m.Jobs.Occupation == "Geek"
& m.Jobs.Occupation.Salaray.Rate >= 1000
select m;
Есть какие-нибудь указатели, как я могу динамически создать этот запрос?Любая помощь очень ценится.Спасибо.
Эрик С.