流畅的NHibernate N + 1问题与复杂的对象

Mor*_*lte 11 nhibernate nhibernate-mapping fluent-nhibernate

我有一个问题,NHibernate查询数据库的方式太多次了.我刚刚意识到它可能与n + 1问题有关,但我无法弄清楚如何改变我的映射来解决问题.

正如您将看到的,我的尝试涉及指定不延迟加载其他对象,但它似乎没有做到这一点.

这是查询:

public IQueryable<Report> ReadAll(DateTime since)
{
    return m_session.QueryOver<Report>()
       .JoinQueryOver(r => r.Mail)
       .Where(m => m.Received >= since)
       .List()
       .AsQueryable();
}
Run Code Online (Sandbox Code Playgroud)

在此先感谢您的回复!如果您需要有关我的对象或映射的更多信息,请告诉我们.

简化对象图(一些省略):

public class Report : EntityBase
{
    public virtual Product Product { get; set; }
    public virtual StackTrace StackTrace { get; set; }
    public virtual Mail Mail { get; set; }

    public virtual IList<ClientUser> ReadBy { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

-

public class Product : EntityBase
{
    public virtual string Name { get; set; }
    public virtual Version Version { get; set; }
    public virtual IList<Report> Reports { get; set; }
    public virtual IList<StackTrace> StackTraces { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

-

public class StackTrace : EntityBase
{
    public virtual IList<StackTraceEntry> Entries { get; set; }
    public virtual IList<Report> Reports { get; set; }
    public virtual Product Product { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

映射示例:

public class ReportMap : ClassMap<Report>
{
    public ReportMap()
    {
        Table("Report");

        References(x => x.User)
          .Column("EndUserId")
          .Not.LazyLoad();

        References(x => x.Product)
          .Column("ProductId")
          .Not.LazyLoad();

        References(x => x.StackTrace)
          .Column("StackTraceId")
          .Not.LazyLoad();

        HasManyToMany(x => x.ReadBy)
          .Cascade.SaveUpdate()
          .Table("ClientUserRead")
          .ParentKeyColumn("ReportId")
          .ChildKeyColumn("ClientUserId")
          .Not.LazyLoad().BatchSize(200);
    }
}
Run Code Online (Sandbox Code Playgroud)

-

public class StackTraceMap : ClassMap<StackTrace>
{
    public StackTraceMap()
    {
        Table("StackTrace");

        References(x => x.Product)
          .Column("ProductId");

        HasMany(x => x.Entries)
          .KeyColumn("StackTraceId")
          .Not.LazyLoad()
          .Cascade
          .All().BatchSize(500);

        HasMany(x => x.Reports)
          .KeyColumn("StackTraceId")
          .Inverse().BatchSize(100);
    }
}
Run Code Online (Sandbox Code Playgroud)

Rad*_*ler 6

要走的路是使用批量提取.在这里阅读更多相关信息:

如何在NHibernate中没有重复的情况下加载加载关联?

在每个实体映射适用(关系 - 避免1 + N)BatchSize many-to-one

public ReportMap()
{
   Table(...)
   BatchSize(25);
   ...
Run Code Online (Sandbox Code Playgroud)

并在每个集合(解决问题one-to-many1 + N)

HasMany(x => x.Reports)
      .KeyColumn("StackTraceId")
      .BatchSize(25)
      ...
Run Code Online (Sandbox Code Playgroud)