簡體   English   中英

Nhibernate / Linq查詢非常慢

[英]Nhibernate/linq query is extremely slow

我正在更新一個用c#/ wpf編寫的項目,它利用了nhibernate和sql server。 當我測試該程序時,我注意到從數據庫中檢索特定列表時非常慢。

以下是數據訪問代碼段:

public static List<Ticket> GetListFromPeriod(DateTime beginDatum, DateTime eindDatum)
    {
        List<Ticket> list = new List<Ticket>();
        using (var session = NhibernateHelper.OpenSession())
        {
            using (var transaction = session.BeginTransaction())
            {
                list = session.Query<Ticket>()
                    .Where(x => x.Tijdstip.Date <= eindDatum && x.Tijdstip.Date >= beginDatum).ToList();
            }
        }
        foreach (var item in list)
        {
            item.IsSaved = true;
        }
        return list;
    }

這小段代碼是麻煩的制造者,大約需要90秒來檢索558個對象:

list = session.Query<Ticket>()
.Where(x => x.Tijdstip.Date <= eindDatum && x.Tijdstip.Date >= beginDatum).ToList();

一些其他信息:

  • 票證TicketRecord有一對多關系
  • 克蘭特 (=英語客戶)與Ticket有一對多關系
  • PapierSoort (英語中的紙張類別)與TicketRecord有一對多關系

映射:

public TicketMap()
    {
        Table("tblTicket");
        Id(x => x.Id)
            .Column("TicketId")
            .UnsavedValue(0)
            .Not.Nullable();
        Map(x => x.Tijdstip)
            .Column("Tickettijdstip")
            .Not.Nullable();
        References(x => x.Klant)
            .Column("KlantId")
            .Not.Nullable();
        HasMany(x => x.TicketRecordsAsList)
            .Table("tblTicketRecord")
            .Inverse()
            .KeyColumn("ticketid").Cascade.All();            
    }


public TicketRecordMap()
   {
       Table("tblTicketrecord");
       Id(x => x.Id)
           .Column("ticketrecordid")
           .Not.Nullable();
       Map(x => x.Prijs)
           .Column("ticketrecordprijs")
           .Not.Nullable();
       Map(x => x.Gewicht)
           .Column("ticketrecordgewicht");
       References(x => x.Soort)
           .Column("soortid")
           .Not.Nullable();
   }

public KlantMap()
    {
        Table("tblKlant");
        Id(x => x.Id)
            .Column("klantid")
            .Not.Nullable();
        Map(x => x.Naam)
            .Column("klantnaam");
        Map(x => x.RijksregisterNr)
            .Column("klantrijksregisternr");
        Map(x => x.Idnr)
            .Column("klantidnr");
        Map(x => x.Adres)
            .Column("klantadres");
        Map(x => x.Actief)
            .Column("actief")
            .Not.Nullable();
    }

public PapierSoortMap()
    {
        Table("tblSoort");
        Id(x => x.Id)
            .Column("papiersoortid")
            .Not.Nullable();
        Map(x => x.Naam)
            .Column("papiersoortnaam")
            .Not.Nullable();
        Map(x => x.Prijs)
            .Column("papiersoortprijs");
        Map(x => x.IsDefault)
            .Column("papierisdefault")
            .Not.Nullable();
    }

Nhibernate助手:

public static class NhibernateHelper
{
    private static ISessionFactory _sessionFactory;

    private static ISessionFactory SessionFactory
    {
        get
        {
            if (_sessionFactory == null)
                InitializeSessionFactory();

            return _sessionFactory;
        }
    }

    private static void InitializeSessionFactory()
    {
        _sessionFactory = Fluently.Configure()
            .Database(MsSqlConfiguration.MsSql2008
            .ConnectionString(x => x.FromConnectionStringWithKey("DBconnect"))
                          //.ConnectionString(
                          //    @"Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Solutions\KassaOPM\KassaOPM.UI\DB.mdf;Integrated Security=True;User Instance=True")
                          .ShowSql())

            .Mappings(m =>
                      m.FluentMappings
                          .AddFromAssemblyOf<KlantMap>()
                          .Conventions.Add(FluentNHibernate.Conventions.Helpers.DefaultLazy.Never()))
            .BuildSessionFactory();
    }

    public static ISession OpenSession()
    {
        return SessionFactory.OpenSession();
    }

}

在SQL Server Profiler中,我發現了三個正在執行的不同查詢:

第一個(僅出現在開頭):

exec sp_executesql N'
select ticket0_.TicketId as TicketId3_, ticket0_.Tickettijdstip as Ticketti2_3_, ticket0_.KlantId as KlantId3_ 
from tblTicket ticket0_ 
where dateadd(dd, 0, datediff(dd, 0, ticket0_.Tickettijdstip))<=@p0 and dateadd(dd, 0, datediff(dd, 0, ticket0_.Tickettijdstip))>=@p1',N'@p0 datetime,@p1 datetime',@p0='2015-04-22 00:00:00',@p1='2015-03-22 00:00:00'

第二和第三個:

exec sp_executesql N'
SELECT klant0_.klantid as klantid0_0_, klant0_.klantnaam as klantnaam0_0_, klant0_.klantrijksregisternr as klantrij3_0_0_, klant0_.klantidnr as klantidnr0_0_, klant0_.klantadres as klantadres0_0_, klant0_.actief as actief0_0_ 
FROM tblKlant klant0_ 
WHERE klant0_.klantid=@p0',N'@p0 int',@p0=4235

exec sp_executesql N'
SELECT ticketreco0_.ticketid as ticketid2_, ticketreco0_.ticketrecordid as ticketre1_2_, ticketreco0_.ticketrecordid as ticketre1_4_1_, ticketreco0_.ticketrecordprijs as ticketre2_4_1_, ticketreco0_.ticketrecordgewicht as ticketre3_4_1_, ticketreco0_.soortid as soortid4_1_, papiersoor1_.papiersoortid as papierso1_1_0_, papiersoor1_.papiersoortnaam as papierso2_1_0_, papiersoor1_.papiersoortprijs as papierso3_1_0_, papiersoor1_.papierisdefault as papieris4_1_0_ 
FROM tblTicketrecord ticketreco0_ inner join tblSoort papiersoor1_ on ticketreco0_.soortid=papiersoor1_.papiersoortid 
WHERE ticketreco0_.ticketid=@p0',N'@p0 int',@p0=27342

我懷疑代碼有問題,但是我似乎無法弄清楚問題出在哪里。

如果您需要任何其他信息,請詢問,我會盡力為您提供所需的信息。

提前致謝

根據第二個和第三個查詢,與滿足日期條件的票證相關的所有一對多映射似乎已在您的業務對象中獲取。

也許您應該聲明一對多關系是懶惰的,以避免額外的(也許是不必要的)加載。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM