Как да въвеждате Cast динамично към низ, докато използвате Contains в Dynamic LINQ?

Искам да използвам динамична LINQ заявка за търсене с някакъв текст във всички свойства в клас. използвам следната функция за създаване на израз. Предавам име на свойство и текст за търсене на метода. В този метод, ако типът на свойството е String, тогава той работи добре. ако типът на свойството е int, DateTime, GUID. тогава не работи.

Както знаем Съдържа метод само за масив от елементи или за низ. Мисля, че стойността на свойството трябва да въведе cast към низ. И така, как да го направя? Решението с обяснение е пълна помощ.

i Събрах код от това.

   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 заявка за съдържа. Настоящият код работи добре с тип данни String. Не работи за други типове данни (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 не мисля, че има начин да го направите директно. Един от начините (на ниво db, ако използвате Sql сървър) може да бъде да имате изчислена колона. Изчислената колона може да съхранява преобразувано представяне на 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