根据子字符串对实体进行排序
本文关键字:排序 实体 字符串 | 更新日期: 2023-09-27 18:32:01
我正在使用带有Code First的EntityFramework 5。
请查看以下 POCO。
public class Product
{
[Key]
public Guid Id { get; set; }
public string Name {get; set; } // e.g. en=Screwdriver;de=Schraubenzieher;fr=Tournevis
/// <summary>
/// This will always return a valid string.
/// </summary>
/// <param name="languageCode"></param>
/// <returns></returns>
public string GetLocalizedName(string languageCode)
{
...
}
}
如您所见,每个产品都有一个"多语言"名称,其中包含此字符串中的所有不同翻译。
我想不出一种简单的方法来使用 LINQ 按某种语言对产品进行排序。我正在寻找的代码应该看起来像这样(假设我想要一个基于英文名称的排序集合):
var sortedProducts = from p in Context.Products
orderby p.GetLocalizedName("en")
select p;
但是一旦我迭代项目,这将不起作用,例如 .ToList(): "LINQ to Entities 无法识别方法 'System.String GetLocalizedName(System.String)' 方法,并且此方法无法转换为存储表达式。
有没有人对如何解决这个问题有一个优雅的想法?结果必须再次是产品类型的IQueryable(如果没有其他方法,我也可以接受产品列表)。
谢谢大家!
结果必须再次是产品类型的IQueryable
这是行不通的。 string GetLocalizedName()
是 C# 方法,这就是出现cannot be translated into a store expression
错误的原因。
(如果没有其他方法,我也可以接受产品列表)。
目前,您需要这样做:
var sortedProducts = from p in Context.Products
.ToList() // switch to IEnumerable and suffer the loss in performance
orderby p.GetLocalizedName("en")
select p;
替代方案:
- 将
GetLocalizedName()
实现为存储过程并修复映射 - 重构数据模型。添加
{ ProductId, LanguageCode, Description }
表。
请注意,排序将在客户端完成。
var sortedProducts = (from p in Context.Products
select p)
.AsEnumerable()
.OrderBy(p => p.GetLocalizedName("en"));
我认为用一个名字管理翻译将是一项艰巨的工作。我会将语言名称拆分为主详细信息:
string code = "de";
var sortedProducts = from p in Context.Products
join l in Context.ProductNames on p.id equals l.product_id
where l.languageCode == code
// you can uncomment the code below to get the english always if the translation in 'code' (german) isn't available, but you need to eliminate duplicates.
// || l.languageCode == "en"
orderby l.localizedName
select new { p.id, p.whatever, l.localizedName };
这样,查询将在服务器端执行。您可以编写查询来查找未翻译的名称。