0

i am using a linq dynamic to do a dynamic orderBy. How do I get only the property names of an entity that is must have a type that is order comparable. The entity has base types (string, ints) and complex objects which I don't the user to filter by.

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();
4

2 回答 2

3

如果你想同时处理IComparableIComparable<>

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?));

两者都返回假。但是可以为空的 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();
于 2013-08-20T09:36:08.983 回答
1

我认为所有支持的类order comparability都应该实现IComparable及其通用版本:

var OrderByOptions = typeof (Project).GetProperties()
                                     .Where(p=>typeof(IComparable).IsAssignableFrom(p.PropertyType))
                                     .Select(x => x.Name).ToList();
于 2013-08-20T09:32:19.597 回答