NHibernate 2nd lvl 缓存、自定义查询、sqldialect

2023-11-29

我买的是 NH 和 FNH 的后备箱版本。当我尝试添加二级缓存时,NHibernate 的某些部分忘记了所选的 sql 方言。


初始配置:

var cfg = Fluently.Configure()
  .Database(MsSqlConfiguration.MsSql2008
    .ConnectionString(connectionString)
    .DefaultSchema("dbo")
    .UseReflectionOptimizer()    
  .Mappings(m => ................);

有罪的自定义查询:

var sql = @"with Foo(col1,col2,col3)
              as (select bla bla bla...)
            Select bla bla bla from Foo";

list = Session.CreateSQLQuery(sql)
  .AddEntity("fizz", typeof(Fizz))
  .SomethingUnimportant();

当我将配置更改为:

var cfg = Fluently.Configure()
  .Database(MsSqlConfiguration.MsSql2008
    .ConnectionString(connectionString)
    .DefaultSchema("dbo")
     .UseReflectionOptimizer()
     .Cache(c=>c
       .UseQueryCache()
         .ProviderClass<HashtableCacheProvider>())
       .ShowSql())
     .Mappings(m => ................);

查询抛出错误(WITHmssql2008中添加了子句):

查询应以“SELECT”或“SELECT DISTINCT”开头

[NotSupportedException:查询应以“SELECT”或“SELECT DISTINCT”开头] NHibernate.Dialect.MsSql2000Dialect.GetAfterSelectInsertPoint(SqlString sql) +179 NHibernate.Dialect.MsSql2000Dialect.GetLimitString(SqlString querySqlString,Int32偏移,Int32限制)+119 NHibernate.Dialect.MsSql2005Dialect.GetLimitString(SqlString querySqlString, Int32 偏移量, Int32 最后) +127 NHibernate.Loader.Loader.PrepareQueryCommand(QueryParameters queryParameters,布尔滚动,ISessionImplementor会话)+725 NHibernate.Loader.Loader.DoQuery(ISessionImplementor会话,QueryParameters queryParameters,布尔returnProxies)+352 NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor会话,QueryParameters queryParameters,布尔returnProxies)+114 NHibernate.Loader.Loader.DoList(ISessionImplementor 会话,QueryParameters 查询参数)+205


有什么想法到底是什么让 nhibernate 感到困惑以及如何解决它吗?


有罪的 NHibernate 代码(在 NHibernate/Dialect/MsSql200Dialect.cs 中):

private static int GetAfterSelectInsertPoint(SqlString sql)
{
  if (sql.StartsWithCaseInsensitive("select distinct"))
  {
    return 15;
  }
  else if (sql.StartsWithCaseInsensitive("select"))
  {
    return 6;
  }
  throw new NotSupportedException
    ("The query should start with 'SELECT' or 'SELECT DISTINCT'");
  }
}

看起来.SetMaxResults(123)导致这种情况。幸运的是,我可以解除该查询的绑定。

希望这能解决这个问题。


我使用 Alkampfer 的解决方案修复了该错误,但我创建了自己的 SQL 方言,而不是直接修补 NHibernate 源代码:

public class Sql2008DialectWithBugFixes : MsSql2008Dialect
{
    public override SqlString GetLimitString(SqlString querySqlString, int offset, int last)
    {
        if (offset == 0)
        {
            return querySqlString.Insert(GetAfterSelectInsertPoint(querySqlString), " top " + last);
        }

        return base.GetLimitString(querySqlString, offset, last);
    }

    private static int GetAfterSelectInsertPoint(SqlString sql)
    {
        Int32 selectPosition;

        if ((selectPosition = sql.IndexOfCaseInsensitive("select distinct")) >= 0)
        {
            return selectPosition + 15; // "select distinct".Length;

        }
        if ((selectPosition = sql.IndexOfCaseInsensitive("select")) >= 0)
        {
            return selectPosition + 6; // "select".Length;
        }

        throw new NotSupportedException("The query should start with 'SELECT' or 'SELECT DISTINCT'");
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

NHibernate 2nd lvl 缓存、自定义查询、sqldialect 的相关文章

  • 自定义字符串查询操作的 Linq to NHibernate 可扩展性?

    我希望能够在 NHibernate Linq 表达式中使用自定义字符串查询 举例来说 这只是一个例子 我希望能够选择包含属性的实体 该属性是特定字符串的字谜 var myEntities EntityRepository AllEntiti
  • Fluent NHibernate 日期时间 UTC

    我想创建一个流畅的 nhibernate 映射来通过以下方式映射 DateTime 字段 保存时 保存 UTC 值 读取时 调整为本地时区值 实现此映射的最佳方法是什么 就我个人而言 我会将日期存储在 UTC 格式的对象中 然后在读 写时在
  • 使用按位运算符时的 HQL 到 CriteriaQuery

    如何将其转换为 CriteraQuery select n from TagRegistration t join t Tag n where t Status status gt 0 order by count t ID desc n
  • 是否可以在不改变作为框架一部分的 DDD 模型的情况下使用 NHibernate

    我挖掘了很多关于DDD方法 无处不在的语言 聚合 存储库等 我认为 与我读到的很多内容相反 实体应该有行为而不是不可知论 我看到的所有例子都倾向于呈现实体虚拟自动属性 and an 空构造函数 受保护或最糟糕的是公开 就是这样 我认为这种对
  • nhibernate:读写字符串列表

    我知道我可以使用 nhibernate 读取写入字符串列表 如下所示 HasMany x gt x Attachments KeyColumn RowId Table PostTable Element PostKey 但这会创建一个额外的
  • NHibernate 和 DateTime 映射的问题

    我在查询时遇到问题 我在给定的范围内选择记录 时间跨度 我从中选择的列的类型为日期 我已经映射了这个 列作为 DateTime 属性 查询可以工作 但速度很慢 生成的查询如下所示 由NH分析器 http nhprof com select
  • NHibernate代理异常

    我是新 NHibernate 我正在编写一个简单的应用程序 其中的客户类包含 id 和名称 并使用 nhibernate 将对象存储到数据库中 但我得到以下信息 未配置 ProxyFactoryFactory 使用可用的 NHibernat
  • 急于获取引用时重复(多对一)

    首先 是的 我正在使用 DistinctRootEntityResultTransformer 我有以下 Fluent NHibernate 映射 public FirstObjectMap Id x gt x Id HasMany
  • 如何将此本机 SQL 查询转换为 HQL

    所以我有这个很长的复杂的 Native SQLQuery string hql SELECT FROM SELECT a rownum r FROM select f2 filmid f2 realisateurid f2 titre f2
  • 无法转换类型为“NHibernate.Collection.Generic.PersistentGenericBag”的对象

    public List
  • 保存时的 NHibernate FlushMode

    我已将 NHibernate 会话上的 FlushMode 属性设置为 FlushMode Never 但是当我调用 session Save User 时 无论如何都会调用数据库 这是应该如何工作的吗 我认为在我调用 Flush 之前它不
  • 如何使用 NHibernate 和 Fluent NHibernate 存储未截断的 varchar(max) 字符串

    我的数据库模式有一个 varchar max 字符串 我读过另一本问题 https stackoverflow com questions 2343105 override for fluent nhibernate for long te
  • MSTest 和 NHibernate

    有谁有让 MSTest 将 hibernate cfg xml 正确复制到输出目录的经验吗 我的所有 MSTest 都因找不到 hibernate cfg xml 错误而失败 我将其设置为 始终复制 但我的 MBUnit 测试通过了 您可以
  • NHibernate:查找脏集合

    我知道怎么做查找脏属性 http nhforge org wikis howtonh finding dirty properties in nhibernate aspx使用NHibernate 但它似乎不适用于集合 即找出是否已在集合中
  • linq查询的问题

    我正在尝试使用 linq to NHibernate 使用 Fluent NHibernate 但我在 linq 查询方面遇到问题 每次我尝试执行它时 我都会收到以下消息 方法 get IsReadOnlyInitialized 类型 NH
  • NHibernate:QueryOver<> 帮助

    我刚刚开始使用 NHibernate 在运行更复杂的查询时遇到了麻烦 我有带有附加标签列表的实体 用户将提供两个标签列表 包括和排除 我需要找到具有所有包含标签的所有实体 并排除在排除列表中具有任何标签的任何实体 下面是我的第一个努力 这显
  • NHibernate QueryOver<> - SubQuery 上的聚合函数

    如何使用 QueryOver 语法编写以下 SQL 语句 SELECT COUNT FROM SELECT FirstName LastName FROM People GROUP BY FirstName LastName as sub
  • NHibernate 二级缓存与 NHibernate Linq Provider 1.0

    如何使用 NHibernate Linq Provider 1 0 启用 NHibernate 二级缓存 二级缓存似乎仅适用于 ICriteria 使用 是的 我终于解决了这个问题 public IQuerable
  • 在 nHibernate 关系中使用实体的 Lite 版本?

    在某些情况下 出于性能原因 创建一个实体的轻量级版本 指向同一个表 但映射的列较少 这是一个好主意吗 例如 如果我有一个包含 50 列的联系人表 并且在一些相关实体中 我可能对 FirstName 和 LastName 属性感兴趣 那么创建
  • 流畅的 Nhibernate 枚举映射

    我有一些问题enum流畅的 NHibernate 中的映射 我知道这个问题已被问过很多次 但我找不到任何适合我的解决方案 我是 NHibernate 的新手 看起来我可能错过了一些简单而愚蠢的事情 这是我的代码 public class D

随机推荐