更新示例以显示更多一般用法。
我有一个允许用户提供本地化的实体:
public class ResourceValue
{
public int ResourceValueId { get; set; }
public string EnglishValue { get; set; }
public string FrenchValue { get; set; }
public string SpanishValue { get; set; }
etc...
}
用于许多其他实体:
public class SomeEntity
{
public int Id { get; set; }
public virtual ResourceValue Name { get; set; }
public virtual ResourceValue ShortDescription { get; set; }
public virtual ResourceValue LongDescription { get; set; }
etc...
}
我想做这样的事情:
return context.SomeEntities.OrderBy(x => x.Name);
让这项工作好像我已经这样做了:
return context.SomeEntities.OrderBy(x => x.Name.FrenchValue);
基于CurrentUICulture为“fr-CA”。
我一直在尝试基于Marc Gravell在这里回答的一些事情:https://stackoverflow.com/a/1231941但是却未能得到我想要的东西。
更新 - 这非常接近,但我宁愿将其命名为“OrderBy”,因此终结编码器可以使用它而无需特别考虑:
public static IOrderedQueryable<TSource> OrderBy<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
{
return ApplyLocalizedOrder(source, keySelector, "OrderBy");
}
public static IOrderedQueryable<TSource> ApplyLocalizedOrder<TSource, TKey>(IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, string methodName)
{
ParameterExpression arg = keySelector.Parameters[0];
Expression expr = Expression.PropertyOrField(keySelector.Body, GetCurrentCulture());
LambdaExpression lambda = Expression.Lambda<Func<TSource, string>>(expr, arg);
return (IOrderedQueryable<TSource>)typeof(Queryable).GetMethods().Single(
method => method.Name == methodName
&& method.IsGenericMethodDefinition
&& method.GetGenericArguments().Length == 2
&& method.GetParameters().Length == 2)
.MakeGenericMethod(typeof(TSource), expr.Type)
.Invoke(null, new object[] { source, lambda });
}
答案 0 :(得分:0)
虽然动态创建lambda表达式很酷,但只需创建一个在查询之上应用排序的方法,就可以以更简单的方式实现结果。该方法看起来像这样:
private static IQueryable<SomeEntity> OrderByName(IQueryable<SomeEntity> source, string culture)
{
if (culture == "fr-CA")
{
return source.OrderBy(x => x.Name.FrenchValue);
}
return source.OrderBy(x => x.Name.EnglishValue);
}
然后你会按如下方式使用它:
OrderByName(context.SomeEntities, "en-US")
以下是整个例子:
public class MyCtx1 : DbContext
{
public DbSet<SomeEntity> SomeEntities { get; set; }
public DbSet<ResourceValue> ResourceValues { get; set; }
}
public class SomeEntity
{
public int Id { get; set; }
public virtual ResourceValue Name { get; set; }
}
public class ResourceValue
{
public int ResourceValueId { get; set; }
public string EnglishValue { get; set; }
public string FrenchValue { get; set; }
}
class Program
{
private static IQueryable<SomeEntity> OrderByName(IQueryable<SomeEntity> source, string culture)
{
if (culture == "fr-CA")
{
return source.OrderBy(x => x.Name.FrenchValue);
}
return source.OrderBy(x => x.Name.EnglishValue);
}
static void Main(string[] args)
{
using (var context = new MyCtx1())
{
if (!context.SomeEntities.Any())
{
context.SomeEntities.Add(
new SomeEntity()
{
Name = new ResourceValue()
{
EnglishValue = "abc - en",
FrenchValue = "xyz - fr"
}
});
context.SomeEntities.Add(
new SomeEntity()
{
Name = new ResourceValue()
{
EnglishValue = "xyz - en",
FrenchValue = "abc - fr"
}
});
context.SaveChanges();
}
Console.WriteLine("Ordered by english name");
DisplayResults(OrderByName(context.SomeEntities, "en-US"));
Console.WriteLine("Ordered by french name");
DisplayResults(OrderByName(context.SomeEntities, "fr-CA"));
}
}
private static void DisplayResults(IQueryable<SomeEntity> q)
{
foreach (var e in q)
{
Console.WriteLine(e.Id);
}
}
结果:
Ordered by english name
1
2
Ordered by french name
2
1
Press any key to continue . . .
答案 1 :(得分:0)
context.SomeEntities.Select(v => v.Name.FrenchName).OrderBy(x => x);
但是,甚至比get
中的名称更好,返回当前文化或某种文化或代码所要求的任何内容,当您的课程可以在Linq查询中执行时,没有理由这样做。当它在课堂上完成时无论如何都会更好,因为那时你调用代码的任何地方都会返回正确的文化。