Как динамически вводить текст в строку при использовании «Содержит» в Dynamic LINQ?

Я хочу использовать динамический запрос LINQ для поиска с некоторым текстом во всех свойствах класса. я использую следующую функцию для создания выражения. Я передаю имя свойства и текст поиска методу. В этом методе, если тип свойства String, он работает нормально. если тип свойства — int, DateTime, GUID. то он не работает.

Как мы знаем, метод contains только для массива элементов или для строки. Я думаю, что значение свойства должно быть приведено к строке. Итак, как это сделать? Решение с пояснением является полной помощью.

я собрал код из этого.

   public static Expression<Func<T, bool>> ContainsExp<T>(string propertyName, string contains)
    {
        var parameterExp = Expression.Parameter(typeof(T), "type");
        var propertyExp = Expression.Property(parameterExp, propertyName);

      MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });


        var someValue = Expression.Constant(contains, typeof(string));
        var containsMethodExp = Expression.Call(propertyExp, method, someValue);

        return Expression.Lambda<Func<T, bool>>(containsMethodExp, parameterExp);

    }

person Kartheek    schedule 11.10.2013    source источник
comment
Не уверен, что понял: вы хотите использовать String.Contains на DateTime?   -  person Raphaël Althaus    schedule 11.10.2013
comment
Обновлен вопрос для лучшего понимания. мне нужен запрос Dynamic Linq для содержимого. Текущий код отлично работает со строковым типом данных. Он не работает для других типов данных (int, DateTime, GUID).   -  person Kartheek    schedule 11.10.2013


Ответы (1)


Ну, вы, наверное, знаете, что невозможно использовать ToString() в linq для сущностей.

Итак, следующий вопрос: как я могу преобразовать другие типы в строку.

Для числовых значений у вас есть SqlFunctions.StringConvert, но есть только перегрузки для double? и decimal?.

Для DateTime вы можете найти что-то с использованием SqlFunctions.StringConvert после применения SqlFunctions.DatePart к вашему DateTime (что, вероятно, означает как минимум 3 вызова SqlFunctions.DatePart для года, месяца, дня)

Для Guid я не думаю, что есть способ сделать это напрямую. Один из способов (на уровне базы данных, если вы используете Sql Server) может состоять в том, чтобы иметь столбец Computed. Вычисляемый столбец может хранить преобразованное в varchar представление вашего GUID. Может быть, есть лучший способ.

В любом случае, вот хотя бы образец, который должен работать как для integer, так и для string:

 public static Expression<Func<T, bool>> ContainsExp<T>(string propertyName, string contains)
        {

            //first, get the type of your property
            var propertyType = typeof(T).GetProperty(propertyName).PropertyType;
            //no change
            var parameterExp = Expression.Parameter(typeof (T), "type");
            Expression propertyExp = Expression.Property(parameterExp, propertyName);
            //if property's type is int
            if (propertyType == typeof (int))
            {
                //convert your Expression to a nullable double (or nullable decimal),
                //so that you can use SqlFunctions.StringConvert
                propertyExp = Expression.Convert(propertyExp, typeof (double?));
                //get the SqlFunctions.StringConvert method for nullable double
                var stringConvertMethod = typeof (SqlFunctions).GetMethod("StringConvert", new[] {typeof (double?)});
                //call StringConvert on your converted expression
                propertyExp = Expression.Call(stringConvertMethod , propertyExp);
            }
            //no change
            var method = typeof (string).GetMethod("Contains", new[] {typeof (string)});


            var someValue = Expression.Constant(contains, typeof (string));
            var containsMethodExp = Expression.Call(propertyExp, method, someValue);

            return Expression.Lambda<Func<T, bool>>(containsMethodExp, parameterExp);

        }
person Raphaël Althaus    schedule 11.10.2013