У меня есть следующая таблица в SQL Server:Сложение Expression Tree конвертированы в действительный SQL динамически, который может сравнить строку с двойниками
ProductAttribute
- Имя:
nvarchar(100)
- Значение:
nvarchar(200)
Это отображается через Entity Framework в мой класс:
public class ProductAttribute
{
public string Name {get;set;}
public string Value {get;set;}
}
Некоторые строки ProductAttributes
имеют следующий вид:
{Name: "RAM", Value: "8 GB"}, {Name: "Cache", Value: "3000KB"}
Мне нужно построить динамически в ExpressionTree, что конвертируется в SQL, который может выполняет следующие действия:
Если значение начинается с рядом следует или не алфавитно-цифровая строка, извлечь номер и сравнить его с заданным значением
double value = ...; Expression<Func<ProductAttribute, bool>> expression = p => { Regex regex = new Regex(@"\d+"); Match match = regex.Match(value); if (match.Success && match.Index == 0) { matchExpression = value.Contains(_parserConfig.TokenSeparator) ? value.Substring(0, value.IndexOf(_parserConfig.TokenSeparator)) : value; string comparand = match.Value; if(double.Parse(comparand)>value) return true; } return false; }
Действительно противно то, что мне нужно конструкции это выражение дерева динамически.
До сих пор мне удалось это (это рассматривает значение как десятичную не как строки, так что даже не пытается сделать все регулярок материал):
private Expression GenerateAnyNumericPredicate(
Type type,
string valueProperty,
string keyValue,
double value) {
ParameterExpression param = Expression.Parameter(type, "s");
MemberExpression source = Expression.Property(param, valueProperty);
ConstantExpression targetValue = GetConstantExpression(value, value.GetType());
BinaryExpression comparisonExpression = Expression.GreaterThan(source, targetValue);
return Expression.Lambda(comparisonExpression, param);
}
EDIT: с помощью представленной ниже, это работает:
Expression<Func<ProductSpecification, bool>> expo = ps=> ps.Value.Substring(0, (SqlFunctions.PatIndex("%[^0-9]%", ps.Value + ".") ?? 0) - 1) == "1000";
Но я также нужен бросок, чтобы удвоить, а затем сравнение чисел, который:
Expression<Func<ProductSpecification, bool>> expo = ps=> double.Parse(ps.Value.Substring(0, (SqlFunctions.PatIndex("%[^0-9]%", ps.Value + ".") ?? 0) - 1)) > 1000;
Очевидно, что это не конвертируется в SQL: double.Parse()
.
Как я могу построить трансляцию, чтобы ее можно было разобрать на SQL из моего выражения?
Каким будет SQL, что вы хотите сгенерировать? –
Честно говоря, я не знаю, но что-то подобное этому. –
Если данные заданы, вы можете столкнуться с проблемой производительности, если этот запрос повторяется снова и снова, возможно, INDEX не может использоваться. Поэтому лучший способ состоит в том, чтобы иметь отдельный числовой столбец с числовым значением, вы можете обновить этот столбец во время вставки/обновления. – sallushan