Nhibernate / linq查询非常慢

时间:2015-04-22 17:58:41

标签: c# nhibernate fluent-nhibernate linq-to-nhibernate

我正在更新用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
  • 有1对多的关系
  • Klant (=英文客户)与 Ticket
  • 有1对多关系
  • PapierSoort (=英文论文类别)与 TicketRecord
  • 有1对多的关系

映射:

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中,我找到了3个不同的查询:

第一个(仅发生在开头):

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

我怀疑代码有问题,但我似乎无法弄清问题是什么。

如果您需要任何其他信息,请询问,我会尽我所能为您提供所需的信息。

提前致谢

1 个答案:

答案 0 :(得分:0)

根据第二次和第三次查询,与满足日期条件的故障单相关的所有一对多映射似乎都在您的业务对象中提取。

也许你应该宣称你的一对多关系是懒惰的,以避免额外的(也许是不必要的)加载。