Frage

Ich habe Stamm Version von NH und FNH. Wenn ich versuche, 2. Level-Cache, einige Teile von NHibernate vergisst gewählt SQLDIALECT hinzuzufügen.


Grundkonfiguration:

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

Guilty benutzerdefinierte Abfrage:

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();

Wenn i-Konfiguration ändern:

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

Abfrage wirft Fehler (WITH Klausel wurde in mssql2008 hinzugefügt):

  

Die Abfrage sollte mit 'SELECT' oder 'SELECT DISTINCT'

starten      

[NotSupportedException: Die Abfrage sollte mit 'SELECT' oder 'SELECT DISTINCT' starten]      NHibernate.Dialect.MsSql2000Dialect.GetAfterSelectInsertPoint (SqlString sql) +179      NHibernate.Dialect.MsSql2000Dialect.GetLimitString (SqlString querySqlString, Int32 Offset, limit Int32) +119      NHibernate.Dialect.MsSql2005Dialect.GetLimitString (SqlString querySqlString, Int32 Offset, Int32 last) +127      NHibernate.Loader.Loader.PrepareQueryCommand (Queryquery, Boolean blättern, ISessionImplementor Sitzung) 725      NHibernate.Loader.Loader.DoQuery (ISessionImplementor Sitzung, Queryquery, Boolean returnProxies) +352      NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections (ISessionImplementor Sitzung, Queryquery, Boolean returnProxies) +114      NHibernate.Loader.Loader.DoList (ISessionImplementor Sitzung, Queryquery) +205


Alle Ideen, was genau verwirrt nHibernate und wie man es beheben?


Guilty NHibernate Code (in 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'");
  }
}

Sieht aus, dass .SetMaxResults(123) verursacht dies. Glücklicherweise kann ich diese Abfrage ungebunden.

Hoffentlich dieses Problem beheben wird.

War es hilfreich?

Lösung

Ich hatte ein ähnliches Problem (Entfernen von SetMaxResults auch dazu beigetragen, aber ich brauchte Paging) und fand heraus, dass die folgende NHibernate Konfigurationseigenschaft diese Fehler verursacht wurde:

<property name="use_sql_comments">true</property>

Es ist sicherlich ein Problem, weil die GetAfterSelectInsertPoint Methode berücksichtigt nicht, dass SQL Kommentare zu der SQL-Abfrage vorangestellt werden können.

Just stellen Sie die use_sql_comments Eigenschaft auf false und das Problem verschwindet.

Andere Tipps

Ich reparierte den Fehler Alkampfer-Lösung, aber ich meinen eigenen SQL-Dialekt, anstatt die NHibernate Quelle gepatcht direkt:

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'");
    }
}

Gerade hatte das gleiche Problem eine ähnliche Abfrage, die eine WITH-Klausel hat.

Leider meine Abfrage auffüllt ein Raster, mit Paging, also muss ich setMaxResults halten.

war meine Lösung neu zu schreiben, eine abgeleitete Tabelle mit:

var sql = @"with Foo(col1,col2,col3)
              as (select x1, x2, x3 from x join y blabla)
            Select col1, col2, col3 from Foo
            join B on B.col1 = Foo.col1";

wird

var sql = @"Select col1, col2, col3 from 
           (select x1 as col1, x2 as col2, x3 as col3 
            from x join y blabla) as Foo
           join B on B.col1 = Foo.col1";

Just ermöglichen NHibernate die "TOP x" Zeichenfolge einzufügen, nachdem die "select" string (6 Zeichen von Anfang an) ... Kein Kommentar: (

T

Es scheint, dass es einige seltsame Fehler in der Routine verwendet, um den Platz in der Abfrage zu finden, die TOP-Klausel (GetAfterSelectInsertPoint), wie gesagt, von Sandor einzufügen. Sie können das Problem beheben direkt in nh Quelle (I gepatcht tatsächlich 2.1 Version, die ich in einem Projekt mit bin, können Sie Details finden Sie hier ). Wenn Sie also unbedingt braucht, damit Kommentare mit use_sql_comments können Sie:)

ich dieses Problem bei der Aktualisierung 1,2-3,2 (ich weiß, BIG springt eh?).

Das Problem in meinem Fall war, dass es ein führender Platz im hql vor der select-Anweisung ist, z.B. String hql = "select" ...

Mit SQL2005 Dialect, diese Abstürze mit einem "System.NotSupportedException: Die Abfrage mit 'SELECT' beginnen sollte ..." message

.

Die Lösung ist

  1. einen Komponententest erstellen, die einen guten Test Driven Entwickler schlägt fehl sollte:)
  2. Entfernen Sie den führenden Platz aus dem „wählen ...“ Anweisung
  3. bauen und führen Sie das Gerät zu testen

Wie ich vorhergesagt -. Entgrenzung select ist akzeptable Lösung

Deleted SetMaxResults und es funktioniert.

Wir liefen in dieser Frage, wenn ein Upgrade auf NHibernate Version 3.3, aber aus einem anderen Grund ... Leerzeichen. Wir hatten eine Menge von SQL-Strings, die so ausgesehen:

var sql = @"
select col1 from MyTable";

oder:

var sql = @" select col1 from My Table";

Diese in der Folge Fehler „Die Abfrage sollte mit‚SELECT‘oder‚SELECT DISTINCT‘Start“, weil NHibernate die Zeichenfolge nicht trimmen, bevor es zu validieren.

Wir haben einen neuen Dialekt, der zuerst die Zeichenfolge trimmt, dies zu umgehen:

public class Sql2008DialectCustom : MsSql2008Dialect
{
  public override SqlString GetLimitString(SqlString queryString, SqlString offset, SqlString limit)
  {
    var trimmedQueryString = queryString.Trim();
    return base.GetLimitString(trimmedQueryString, offset, limit);
  }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top