假设我有以下简单设置:
public enum Status
{
Pending = 0,
Accepted = 1,
Rejected = 2
}
public class MyEntity
{
public Status Status { get; set; }
}
...我希望对两种不同语言的 Status
进行以下升序排序:
Language 1: 1, 0, 2
Language 2: 0, 1, 2
在 Entity Framework 中有没有一种简单的方法可以做到这一点?我觉得这可能是一种常见的情况。
我认为唯一的方法是维护一个单独的表,其中包含状态的所有翻译...然后根据用户当前的语言按该表中的名称列排序。不过,我想看看是否有人有任何其他想法。
您可以在没有单独表的情况下编写查询,但这并不漂亮。也不是很灵活。由于 EF 依赖于众所周知的方法来映射到等效的 SQL 函数,因此您不能插入自定义函数。但是,您可以使用 let
手动设置顺序:
var query = from e in MyEntity
let sortOrder = UserLanguage == Language1 // Handle Language 1 Sort
? e.Status == Pending
? 1 : e.Status == Accepted ? 0 : 2
: e.Status == Pending // Handle Language 2 sort
? 0 : e.Status == Accepted ? 1 : 2
orderby sortOrder
select e
这仅适用于两种语言。我能想到的另一种方法是自己编写表达式树。这样做的好处是您可以为每种语言拆分逻辑。我们可以提取三元条件逻辑并将它们放在扩展静态类中。这是它的外观示例:
public static class QuerySortExtension
{
private static readonly Dictionary<string, Expression<Func<MyEntity, int>>> _orderingMap;
private static readonly Expression<Func<MyEntity, int>> _defaultSort;
public static IOrderedQueryable<MyEntity> LanguageSort(this IQueryable<MyEntity> query, string language)
{
Expression<Func<MyEntity, int>> sortExpression;
if (!_orderingMap.TryGetValue(language, out sortExpression))
sortExpression = _defaultSort;
return query.OrderBy(sortExpression);
}
static QuerySortExtension()
{
_orderingMap = new Dictionary<string, Expression<Func<MyEntity, int>>>(StringComparer.OrdinalIgnoreCase) {
{ "EN", e => e.Status == Status.Pending ? 1 : e.Status == Status.Accepted ? 0 : 2 },
{ "JP", e => e.Status == Status.Pending ? 2 : e.Status == Status.Accepted ? 1 : 0 }
};
// Default ordering
_defaultSort = e => (int)e.Status;
}
}
你可以这样使用下面的方法:
var entities = new[] {
new MyEntity { Status = Status.Accepted },
new MyEntity { Status = Status.Pending },
new MyEntity { Status = Status.Rejected }
}.AsQueryable();
var query = from e in entities.LanguageSort("EN")
select e;
var queryJp = from e in entities.LanguageSort("JP")
select e;
Console.WriteLine("Sorting with EN");
foreach (var e in query)
Console.WriteLine(e.Status);
Console.WriteLine("Sorting with JP");
foreach (var e in queryJp)
Console.WriteLine(e.Status);
输出如下:
Sorting with EN
Accepted
Pending
Rejected
Sorting with JP
Rejected
Accepted
Pending
我是一名优秀的程序员,十分优秀!