说我有以下简单的设置:
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
在实体框架中有一种简单的方法吗?我觉得这可能是一种常见的情况。
我认为唯一的方法是维护一个单独的表,其中包含Status的所有翻译...然后根据用户当前语言按该表中的name列排序。我想知道是否有人有任何其他想法。
答案 0 :(得分:2)
EF将根据您将枚举映射到的DB列的类型(可能是int)进行排序,因此它的排序方式与对int进行排序的方式相同。
如果你想要某种自定义分类器,你必须自己编写并在内存中排序。
不确定我理解你的单独表格概念,你能不能提供更多细节。
答案 1 :(得分:2)
你可以在没有单独的表的情况下编写查询,但它并不漂亮。它也不是很灵活。由于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
答案 2 :(得分:0)
我接受了西蒙的回答,因为它可以替代我在问题中提到的内容。这是一种方法,我想出了如何使用一个有效的单独表。明显的缺点是你必须在数据库中维护翻译......
public enum Status
{
Pending = 0,
Accepted = 1,
Rejected = 2
}
public class MyEntity
{
public int MyEntityID { get; set; }
public Status Status { get; set; }
}
public enum Language
{
Language1 = 0,
Language2 = 1
}
public class StatusTranslation
{
public int StatusTranslationID { get; set; }
public Language Language { get; set; }
public Status Status { get; set; }
public string Name { get; set; }
}
以任何方式将所有翻译插入SQL表:
INSERT INTO StatusTranslations (Language, Status, Name) VALUES (0, 0, "Pending")
// etc...
INSERT INTO StatusTranslations (Language, Status, Name) VALUES (1, 0, "En attendant")
// etc...
现在加入并排序:
var userLanguage = Language.Language1;
var results = db.MyEntities.Join(
db.StatusTranslations,
e => e.Status,
s => s.Status,
(e, s) => new { MyEntity = e, Status = s }
)
.Where(e => e.Status.Language == userLanguage)
.Select(e => new {
MyEntityID = e.MyEntity.MyEntityID
StatusName = e.Status.Name
}).OrderBy(e => e.StatusName).ToList();
我从来没有编译过这个示例代码(只有我自己的代码)所以我为任何错误道歉,但它应该给出足够好的想法。