1

Ich bin neu in NHibernate. Ich erhalte Select N + 1 Warnung, wenn ich meine Abfrage von NHibernate Profiler teste. Ich bin nicht sicher, was mache ich falsch mit meiner Zuordnung oder Abfrage.Erhalten von NHibernate Wählen Sie N + 1

Grundsätzlich habe ich eine Tabelle namens Header und es hat viele Details. Für jedes Detail habe ich eine Wiederholung. d.h

ein Header-> viele Details ein Detail -> ein Replay

Abfrage:

var query = _session.QueryOver(() => headerAlias) 
        .Where(() => headerAlias.ScriptNumber == scriptId) 
        .And(() => headerAlias.ChannelCode == channelId) 
        .Future<ProgramHeader>(); 

Meine Mapping:

public ProgramHeaderMap() 
{ 
    Table("S_IDB_M_PROG_HDR"); 

    CompositeId() 
     .KeyProperty(x => x.ScriptNumber, "PROGCD") 
     .KeyProperty(x => x.ChannelCode, "CHCD"); 

    Map(x => x.ChannelCode).Column("CHCD"); 
    Map(x => x.ShowCode).Column("SHOWCD"); 
    Map(x => x.ShowStartTime).Column("ONAIRSTART"); 
    Map(x => x.ShowEndTime).Column("ONAIREND"); 
    Map(x => x.Presenters).Column("HOST"); 
    Map(x => x.Guests).Column("GUEST"); 
    Map(x => x.Planners).Column("PLANNER"); 
    Map(x => x.ModifiedTime).Column("UPDDATE"); 

    HasMany(x => x.Pal) 
      .AsBag() 
      .Inverse() 
      .KeyColumns.Add("PROGCD", "CHCD") 
      .Cascade.All() 
      .Not.LazyLoad(); 
} 

Detailkarte:

public ProgramDetailMap() 
{ 
    Table("S_IDB_M_PROG_DTL"); 

    CompositeId() 
     .KeyProperty(x => x.ScriptNumber, "PROGCD") 
     .KeyProperty(x => x.ChannelCode, "CHCD") 
     .KeyProperty(x => x.ProductNumber, "PRODCD") 
     .KeyProperty(x => x.ColorCode, "COLORCD") 
     .KeyProperty(x => x.SizeCode, "SIZECD"); 

    Map(x => x.PromoCode,"PCPARAM1"); 
    Map(x => x.EasyPayInstalments,"EZINST"); 
    Map(x => x.EasyPayFirstAmount,"EZAMT"); 
    Map(x => x.EasyPayNextAmount,"EZAMT2"); 
    Map(x => x.UpdatedDate).Column("UPDDATE"); 

    References(x => x.ProgramHeader) 
     .Columns("PROGCD", "CHCD") 
     .LazyLoad(); 

    References(x => x.Replay) 
     .Columns("PROGCD", "CHCD", "PRODCD", "COLORCD", "SIZECD") 
     .NotFound.Ignore(); 
} 

}

Replay:

public ProgramReplayMap() 
{ 
    Table("S_IDB_M_PROG_REPL"); 

    CompositeId() 
     .KeyProperty(x => x.ScriptNumber, "PROGCD") 
     .KeyProperty(x => x.ChannelCode, "CHCD") 
     .KeyProperty(x => x.ProductNumber, "PRODCD") 
     .KeyProperty(x => x.ColorCode, "COLORCD") 
     .KeyProperty(x => x.SizeCode, "SIZECD"); 

    Map(x => x.Price, "REC_PRICE"); 
    Map(x => x.Postage, "REC_POSTAGE"); 
    Map(x => x.UpdatedDate).Column("UPDDATE"); 
} 

eine Antwort für diese Abfrage zu schätzen wissen.

Dank

+0

Verstehen Sie, was "SELECT N + 1" bedeutet? –

+0

Ein bisschen. Angenommen, es gibt eine Sammlung von irgendeinem Objekt und jedes Objekt hat eine Sammlung von einem anderen Objekt, d. H. 1 zu vielen Relationen. SELECT N + 1 ist eine Auswahlabfrage für das Hauptobjekt und N zusätzlich auswählen, um die Sammlung abzurufen. Hoffe, das ist richtig –

+0

Ich will nur wissen, ob meine Mappings richtig sind –

Antwort

0

Was Sie als Ausgangspunkt wollen, ist Batch Fetching zu ermöglichen. Die Dokumentation ist bei http://nhibernate.info/doc/nhibernate-reference/performance.html#performance-fetching-batch

In FluentNHibernate es als .BatchSize() Methoden auf dem ClassMap verfügbar ist und auf Sammlung Zuordnungen.

Batch-Abruf bedeutet, dass NHibernate eine Reihe von verwandten Instanzen desselben Typs auf einmal abrufen kann. Wenn Sie beispielsweise 20 Instanzen von A geladen haben, die jeweils einen verzögerten Verweis auf B enthalten, kann NHibernate alle 20 B-Instanzen mit einer Abfrage laden, sobald Sie auf eine der B-Instanzen zugreifen. Wenn Sie auf eine der referenzierten B-Instanzen zugreifen, ist es wahrscheinlich, dass Sie bald auch auf die anderen Instanzen zugreifen werden und dass das Laden von 20 Instanzen mit derselben Abfrage so schnell ist, dass es nicht viel bedeutet, wenn wir laden ein paar, die nicht wirklich benötigt werden. (Die Zahl 20 ist, was Sie mit der Einstellung der Stapelgröße steuern.)