2013-08-20 1 views
0

Я использую динамическую динамику linq для динамического orderBy. Как получить только имена свойств объекта, который должен иметь тип, сопоставимый по порядку. Объект имеет базовые типы (строка, ints) и сложные объекты, которые я не фильтрую для пользователя.тест, если свойство в сущности можно заказать, используя orderBy

var OrderByOptions = typeof (Project).GetProperties().Select(x => x.Name).ToList(); //I only want order comparable property names here 

var userSelectable = 2; 

var pjs = _pjRepo.Projects.Where(x => x.Active == true).OrderBy(OrderByOptions[userSelectable]).ToList(); 

ответ

3

, если вы хотите, чтобы обрабатывать как IComparable и IComparable<>

var OrderByOptions = (from p in typeof(Project).GetProperties() 
         let type = p.PropertyType 
         where typeof(IComparable).IsAssignableFrom(type) || 
          typeof(IComparable<>).MakeGenericType(type).IsAssignableFrom(type) 
         select p.Name).ToArray(); 

Обратите внимание, что если вы делают заказ на стороне сервера, нет гарантии, что IComparable/IComparable<T> будет одинаковым в SQL. Например:

bool b1 = typeof(IComparable).IsAssignableFrom(typeof(int?)); 
bool b2 = typeof(IComparable<int?>).IsAssignableFrom(typeof(int?)); 

оба возвращаются ложные. Но nullable int, безусловно, сопоставим в SQL.

Возможно, белый список будет лучше.

public static readonly HashSet<Type> ComparableTypes = new HashSet<Type> 
{ 
    typeof(bool), typeof(bool?), 
    typeof(char), typeof(char?), 
    typeof(string), 
    typeof(sbyte), typeof(sbyte?), typeof(byte), typeof(byte?), 
    typeof(short), typeof(short?), typeof(ushort), typeof(ushort?), 
    typeof(int), typeof(int?), typeof(uint), typeof(uint?), 
    typeof(long), typeof(long?), typeof(ulong), typeof(ulong?), 
    typeof(float), typeof(float?), 
    typeof(double), typeof(double?), 
    typeof(decimal), typeof(decimal?), 
    typeof(DateTime), typeof(DateTime?), 
    typeof(DateTimeOffset), typeof(DateTimeOffset?),     
    typeof(TimeSpan), typeof(TimeSpan?), 
    typeof(Guid), typeof(Guid?), 
}; 

var OrderByOptions = (from p in typeof(Project).GetProperties() 
         let type = p.PropertyType 
         where ComparableTypes.Contains(type) 
         select p.Name).ToArray(); 
+2

Вы должны поменять положение' type' и 'TypeOf (IComparable)', я сделал то же самое, но я понял, что 'typeof (IComparable)' будет идти первым. Метод 'IsAssignableFrom' иногда меня смущает. Небольшой тест 'typeof (int) .IsAssignableFrom (typeof (IComparable)) = false'? но 'typeof (IComparable) .IsAssignableFrom (typeof (int)) = true' <== Вот что должно быть. –

+0

@KingKing Вы правы. Сделано – xanatos

+0

+1 для нулевых значений и белого списка – SWeko

1

Я думаю, что все класс поддержки order comparability должны осуществлять IComparable и его дженерик:

var OrderByOptions = typeof (Project).GetProperties() 
            .Where(p=>typeof(IComparable).IsAssignableFrom(p.PropertyType)) 
            .Select(x => x.Name).ToList(); 
+0

Не 'p.GetType()', 'p.PropertyType' – xanatos

+0

@xanatos благодаря –

Смежные вопросы