我正在开发一个首先使用 EF 代码的 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
and 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
桌子可能相当大。
我想过打电话ToListAsync
就在之后entities.Items.Where(itemFilter)
但这将返回所有过滤的项目,尽管我只需要一页。听起来不是一个好主意。
但如果我不这样做EF
不会知道GetDescription()
方法,我只能想到两个解决方案:
- 将我的数据库列更改为字符串(枚举描述)而不是枚举本身(但对我来说听起来像是黑客)
- 或按字母顺序排列MyEnumE
组件直接在enum
声明(看起来很脏而且也很难维护)
我很困惑,因为我担心打电话时的表现ToListAsync
过滤后,所有其他解决方案看起来都很脏,我绝对需要一个IPagedList
从返回的Search
method.
有人知道如何处理这个问题吗?
多谢。
UPDATE
这里是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
(using Linq
而不是存储过程等),因此该解决方案似乎比创建引用表更适合我的特定情况。
However Niyoko Yuliawan
's and Michael Freidgeim
对我来说也是很好的答案,任何阅读这篇文章并拥有更多数据库方法的人都应该寻求他们的解决方案;)
非常感谢大家。