我有一個名爲類HomeInfo
字符串條件<T>
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 EstimatedValue < 60000」或「EstimatedValue < 50000」
我不知道我怎樣纔能有效地對「名單listHomeInfo」適用這個條件,因爲遠我知道List<T>.Where()
不支持字符串條件。我知道一個解決方法是將列表轉換爲DataTable並使用Select(string expression)
方法,然後將DataRow[]
轉換爲List<HomeInfo>
,但我認爲可能有更好的方法來實現這一點。
[編輯]
我創建了兩個方法來幫助我,但我得到的例外「的二元運算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;
}
}
你爲什麼想要保存條件爲一個字符串?它是由用戶輸入的嗎?爲什麼不使用表達式樹? –
'List.Where()不支持字符串條件' - 確實如此,如果字符串是你正在評估的條件。 –
這個例子看起來並不需要如此高度的自定義將查詢放在一起,但總是有[動態LINQ庫](http://weblogs.asp.net/scottgu/archive/2008/01 /07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx)。 – herzmeister