c# - NHibernate LINQ 查询中的关键回退

标签 c# linq nhibernate

啊!

我正在为一个在 SQL 数据库上使用 NHibernate 的 Web 应用程序编写一个带有语言环境回退的消息存储。例如,store.Get("Greet", "fr-ca-on") 的结果将是此数据的最佳匹配值 (fr-ca ):

Key    Locale    Message
-----  ------    --------
Greet            Hello
Greet  fr        Bonjour!
Greet  fr-ca     Âllo!
Greet  fr-ca-qc  Âllo toi!

我已经尝试过像这样的各种查询来实现回退:

string[] locales = new[] { "fr-ca-on", "fr-ca", "fr", "" }; 
return (
   from Translation translation in reader.Get<Translation>()
   where locales.Contains(translation.Locale)
   group translation by translation.Key into translationGroup
   select translationGroup.OrderByDescending(p => p.Locale.Length).First()
   //or: select translationGroup.MaxBy(p => p.Locale.Length)
);

这些在内存中工作得很好,但 NHibernate 不能将组选择转换成 SQL。 (它似乎只支持简单的聚合方法,如 .Count(),不支持选择。)

我如何重写这个查询以便 NHibernate 可以将它翻译成 SQL?我想不出一种不涉及提前将查询延迟到内存中的方法,这确实会损害应用程序的性能。

(我不想使用资源文件,因为我有其他与翻译相关的实体。)

最佳答案

我能够将其重写为 LINQ 子查询:

string[] locales = new[] { "fr-ca-on", "fr-ca", "fr", "" }; 
return (
    from Translation translation in reader.Get<Translation>()
    where
        locales.Contains(translation.Locale)
        && (translation.Locale.Length == reader
            .Get<Translation>()
            .Where(p => locales.Contains(p.Locale) && p.Key == translation.Key)
            .Max(p => p.Locale.Length)
        )
    select translation
);

NHibernate 很好地处理子查询并将其转换为这个(美化的)SQL:

SELECT *
FROM [translation] translation
WHERE
    [locale] IN ('fr-ca-on', 'fr-ca', 'fr', '')
    AND LEN([locale]) = (
        SELECT CAST(MAX(LEN(sub.[locale])) AS INT)
        FROM [translation] sub
        WHERE
           sub.[locale] IN ('fr-ca-on', 'fr-ca', 'fr', '')
           AND sub.[key] = translation.[key]
)

关于c# - NHibernate LINQ 查询中的关键回退,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12208016/

相关文章:

c# - XSS 改变 ASP.NET session 状态

c# - 如何使用直线 API 将机器人集成到网站

c# - 使用同义词库的句子生成器

c# - 如何模拟/ stub Nhibernate QueryOver 调用?

c# - 在 LINQ-to-NHibernate 或 LINQ 中比较枚举时有什么考虑吗?

c# - Web 服务中的通用类型 WebMethod

c# - 我如何比较和搜索字符串和日期时间 C#

c# - 我是否误解了 LINQ to SQL .AsEnumerable()?

c# - linq 如何选择具有包含一个或多个值数组(或列表)的子集合的父项

c# - NHIbernate <any> 映射问题