我正在使用EF Code First开发ASP.NET MVC项目,遇到了一个需要按枚举描述排序的情况:
public partial class Item
{
public enum MyEnumE
{
[Description("description of enum1")]
Enum1,
[Description("description of enum2")]
Enum2,
...
}
public MyEnumE MyEnum { get; set; }
}
这里是
Search
和SortAndPaginate
函数:注:该文本原为中文,已翻译为英文。
public async Task<IPagedList<Item>> Search(ItemCriteria criteria, SortableTypeE sortName, SortOrder.TypeE sortOrder, int pageNb)
{
var itemFilter = GenerateFilter(criteria);
var items = entities.Items.Where(itemFilter);
return await SortAndPaginate(items, sortName, sortOrder, pageNb);
}
private async Task<IPagedList<Item>> SortAndPaginate(IQueryable<Item> items, SortableTypeE sortName, SortOrder.TypeE sortOrder, int pageNb)
{
IOrderedQueryable<Item> result = null;
switch (sortName)
{
...
case SortableTypeE.Type:
result = sortOrder == SortOrder.TypeE.ASC
? items.OrderBy(i => i.MyEnum.GetDescription())
: items.OrderByDescending(i => i.MyEnum.GetDescription());
result = result.ThenBy(i => i.SomeOtherProperty);
break;
...
}
if (result != null)
{
return await result.ToPagedListAsync(pageNb, 10);
}
return PagedListHelper.Empty<Item>();
}
问题在于
Item
表可能非常庞大。我考虑在
entities.Items.Where(itemFilter)
之后立即调用ToListAsync
,但这将返回所有经过筛选的项,尽管我只需要一页。听起来不是一个好主意。但如果我不这样做,
EF
就不会知道GetDescription()
方法,我只能想到两个解决方案:-将我的数据库列更改为字符串(枚举描述),而不是枚举本身(但对我来说听起来像是一种hack)
-或者直接在
enum
声明中按字母顺序排序MyEnumE
组件(看起来很肮脏,也很难维护)我陷入了困境,因为我担心如果在筛选后立即调用
ToListAsync
,性能会受到影响,所有其他解决方案都看起来有些问题,而我绝对需要从Search
方法返回IPagedList
。是否有人能想出如何处理这个问题的主意呢?
非常感谢。
更新
这是
GetDescription
方法(如果需要,可以更改它):public static string GetDescription(this Enum e)
{
FieldInfo fi = e.GetType().GetField(e.ToString());
DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes.Length > 0)
return attributes[0].Description;
else
return e.ToString();
}
解决方案
我最终会选择Ivan Stoev的建议,因为我的项目主要基于Linq
(使用Linq
而不是存储过程等),所以这个解决方案似乎比创建引用表更适合我的特殊情况。
然而,Niyoko Yuliawan
和Michael Freidgeim
的答案对我来说也非常好,任何阅读此帖子并采用更多数据库方法的人应该采用他们的解决方案;)
非常感谢大家。
GetDescription
方法吗? - Ivan Stoev