Pat*_*ick 2 c# linq expression expression-trees
所以这是我想要实现的基础:
string.Format(new CultureInfo("da-DK"), "{0:n}", myDouble)
Run Code Online (Sandbox Code Playgroud)
(用文化格式化数字.示例输入:1,输出:"1,00")
上下文:我需要使用表达式树实现这一点,我当前的代码生成一个搜索查询,通过产品价格,它应该格式化双精度.这是我到目前为止所得到的:
var query = context.Products;
var searchquery = "1,00" //example
var propertyName = "Price"; //example
var parameterExp = Expression.Parameter(typeof(ProductClass), "type");
var propertyExp = Expression.Property(parameterExp, propertyName);
MethodCallExpression propertyExpToStringToLower; //value initialized depending on type.
if (propertyExp.Type == typeof(double))
{
// Example value: 1, needed value: "1,00".
// Here I want to change the double to the correct format, ToString.
}
else
{
//ToString's and ToLower's other attributes (string, int, where no format is needed)
propertyExpToStringToLower = Expression.Call(Expression.Call(propertyExp, propertyExp.Type.GetMethod("ToString", System.Type.EmptyTypes)), typeof(string).GetMethod("ToLower", System.Type.EmptyTypes));
}
MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
var seachValue = Expression.Constant(searchquery.ToLower(), typeof(string));
var containsMethodExp = Expression.Call(propertyExpToStringToLower, method, seachValue);
Expression<Func<ProductClass, bool>> predicate = Expression.Lambda<Func<ProductClass, bool>>
(containsMethodExp, parameterExp);
query = query.Where(predicate);
Run Code Online (Sandbox Code Playgroud)
作为一个快速的注释,我对表达式树不是很有经验但是代码正在使用像ProductName这样的字符串属性,而不是使用数字.我的图像我可以用格式调用ToString吗?但我找不到任何例子.
问题:如何使用格式/文化格式化表达式值?
尝试为string.Format(new CultureInfo("da-DK"), "{0:n}", myDouble)(或ToString(new CultureInfo("da-DK")))调用构建表达式树是不值得的,因为您正在将此表达式树与Entity Framework一起使用,并且它无法将此类语句转换为SQL查询.
而不是尝试将数据库值转换为所需的文化 - 将您的输入转换为文化数据库期望:
var searchquery = "1,00"; //example
var expectedCulture = new CultureInfo("da-DK");
var targetCulture = new CultureInfo("en-US"); // for example
double searchValue;
if (double.TryParse(searchquery, NumberStyles.AllowDecimalPoint, targetCulture, out searchValue)) {
searchquery = searchValue.ToString(targetCulture);
}
Run Code Online (Sandbox Code Playgroud)
如果你将走这条路 - 你可能会注意到实际上可能没有必要将数字转换回字符串,因为你现在知道它是一个数字 - 你可以将它与equals进行比较,而不是ToString().Contains(...)像你现在所做的那样.ToString().Contains(...)将生成相当糟糕的SQL查询,将强制评估表中的每一行.如果您将直接比较价格(即,如:)c => c.Price == doubleValue- 您将能够在该列上使用数据库索引(如果有的话),即使没有索引,我也希望它能够更快地执行.但请注意,这种比较并不完全相同Contains(...).例如,如果用户键入"1.00" - 包含将返回"111.00","231.00"等价格,而等式比较将返回完全匹配.Contains在搜索价格时是否需要使用- 只有您可以决定.
旁注:使用double价格时使用是一个坏主意.请decimal改用.