という名前のクラスがありますHomeInfo
public class HomeInfo
{
public int ID {get;set;}
public string OwnerName {get;set;}
public string Address {get;set;}
public int EstimatedValue {get;set;}
}
サーバーからデータを取得し、それを追加しますList<HomeInfo> listHomeInfo
私のGUIでは、ユーザー入力に基づいて結果をフィルタリングできるようにする必要があるため、クライアントは推定値のテキストボックスが必要で、そこに「> 30kおよび<50k」または「> 50k」などのテキストを入力したいので、これらを解析して変換しましたクラスの値と作成されたオブジェクト
public class ExpressionValue
{
public float? FirstDigit { get; set; }
/// <summary>
/// >, >=, <,<=
/// </summary>
public string FirstExpCondition { get; set; }
/// <summary>
/// OR, AND
/// </summary>
public string ConditionOperator { get; set; }
public float SecondDigit { get; set; }
public string SecondExpCondition { get; set; }
}
ExpressionValue オブジェクトを使用すると、適切な条件文字列を作成できます。これで、「EstimatedValue > 30000 AND EstimatedValue < 60000」または「EstimatedValue < 50000」のような条件文字列を作成できるようになりました
私が知る限り、List<T>.Where()
文字列条件をサポートしていないため、「List listHomeInfo」にこの条件を効果的に適用する方法がわかりません。それを回避する方法は、リストを DataTable に変換し、Select(string expression)
メソッドを使用してから に変換することですが、これを達成するためのより良い方法があると思います。DataRow[]
List<HomeInfo>
[編集]
私を助けるために2つのメソッドを作成しましたが、「二項演算子GreaterThanは、タイプ 'System.Single'および 'System.Double'に対して定義されていません。BinaryExpression を作成するとき。
public static Expression<Func<T, bool>> ParseExpressionCondition<T>(string expression, string fieldName)
{
try
{
string decimalNumRegex = @"\d+(\.\d{1,2})?";
List<string> matchPatterns = new List<string>() { ">=", ">", "<=", "<" };
ExpressionValue expValue = new ExpressionValue();
Dictionary<string, string> conditions = new Dictionary<string, string>();
var parameter = Expression.Parameter(typeof(T), typeof(T).ToString());
//var lhs = Expression.GreaterThan(Expression.Property(parameter, "EstimatedValue"), Expression.Constant(30000));
BinaryExpression lhs = null, rhs = null;
object objectValue = null;
string condOperator = null;
foreach (string pattern in matchPatterns)
{
Match match = Regex.Match(expression, pattern + decimalNumRegex);
if (match.Success)
{
//get digit part
double digit = double.Parse(Regex.Match(match.Value, decimalNumRegex).Value);
if (!expValue.FirstDigit.HasValue)
{
objectValue = digit;
condOperator = match.Value.Replace(digit.ToString(), "");
lhs = GetBinaryExpression(parameter, fieldName, objectValue, condOperator);
}
else
{
objectValue = digit;
condOperator = match.Value.Replace(digit.ToString(), "");
rhs = GetBinaryExpression(parameter, fieldName, objectValue, condOperator);
}
}
}
if (expression.ToLower().Contains("and"))
return Expression.Lambda<Func<T, bool>>(Expression.And(lhs, rhs), parameter);
else if (expression.ToLower().Contains("or"))
return Expression.Lambda<Func<T, bool>>(Expression.Or(lhs, rhs), parameter);
return null;
}
catch (Exception ex)
{
Logger.WriteLog(ex);
throw ex;
}
}
private static BinaryExpression GetBinaryExpression(ParameterExpression paraExp, string fieldName, object expressionValue, string conditionOperator)
{
try
{
BinaryExpression binExp = null;
MemberExpression expressionLeft = Expression.Property(paraExp, fieldName);
Expression expressionRight = Expression.Constant(expressionValue );
switch (conditionOperator)
{
case ">":
binExp = Expression.GreaterThan(expressionLeft, expressionRight);
break;
case ">=":
binExp = Expression.GreaterThanOrEqual(expressionLeft, expressionRight);
break;
case "<":
binExp = Expression.LessThan(expressionLeft, expressionRight);
break;
case "<=":
binExp = Expression.LessThanOrEqual(expressionLeft, expressionRight);
break;
}
return binExp;
}
catch (Exception ex)
{
throw ex;
}
}