【问题标题】:Nhibernate generating too many queries for one to one mappingNhibernate 为一对一映射生成太多查询
【发布时间】:2013-01-30 08:02:24
【问题描述】:

当应用程序加载时,我将所有广告系列都加载到内存中:

var all = session.Query<Campaign>().ToList();

广告系列只有一项服务。

public CampaignMap()
{
  Table("`TR_Campaigns`");
  Schema("dbo");
  Not.LazyLoad();
  Id(x => .Id).GeneratedBy.Increment().Column("CampaignID");
  References(x => x.Service).Column("ServiceID").Not.LazyLoad();
  // I also tried hasone and it is bringing the same result
}

这是服务地图:

public ServiceMap()
{
  Not.LazyLoad();
  Table("`TR_Services`");
  Id(x => x.Id, "ServiceID").GeneratedBy.Increment();
  Map(x => x.Name,"ServiceName");
}

问题是,当我有 100 个广告系列,并且每个广告系列都有不同的服务时,映射会生成 100 个查询来获取每个广告系列的服务。 例如,如果 ServiceID 2 在多个活动中重复出现,则查询 … WHERE service0_.ServiceID = 2 将只运行一次(这很好)。

这是生成的查询:

SELECT service0_.ServiceID   as ServiceID4_0_,
       service0_.ServiceName as ServiceN2_4_0_
FROM   [TR_Services] service0_
WHERE  service0_.ServiceID = 8

这正常吗?当我有 1000 个活动和 1000 项服务甚至更多时,我会怎么做……

谢谢

更新
我看到了您的编辑,我认为这是有效的。
但是CampaignMap的关系比较多,例如:

 HasMany(x => x.LandingPageWeights).KeyColumn("CampaignID").Not.LazyLoad();

根据您的查询,我该如何处理?
执行 LandingPageWeights = x.LandingPageWeights 失败....
您对此有何建议?
谢谢

【问题讨论】:

    标签: nhibernate one-to-one


    【解决方案1】:

    阅读这篇文章可以避免n+1问题

    http://ayende.com/blog/1328/combating-the-select-n-1-problem-in-nhibernate

    这样回答

    Prevent Fluent NHibernate select n+1

    编辑

    选择所有没有 n+1 问题的数据

    var items = session.Query<Campaign>().Select(x=> new Campaign
    {
      Id = x.Id,
      Service = new Service
      {
         Id = x.Service.Id,
         Name = x.Service.Name
      }
    }).ToList();
    

    【讨论】:

    • 谢谢。我知道这一点,但我从未在一对一的情况下看到它,这就是我问它的原因。
    • @SexyMF 我认为是因为您没有惰性列服务。您可以使用 linq 投影查询或连接来避免它
    • 恕我直言,fetch-joins 不是一个好建议,有几个问题(例如分页、多个列表、不同的根问题等)。 Ayendes 的博客来自 2006 年。
    • @Stefan Steinegger 完全同意
    • @SexyMF 那么你应该从 session.Query() 开始,选择所有后,将数据转换为服务器端的 Campaign->LandingPageWeight
    【解决方案2】:

    我想我找到了。 我已减少到 2 个查询:

    var all = session.Query<Campaign>()
                                .Fetch(x => x.Service)
                                .Fetch(x => x.Supplier)
                                .ToList();
    

    这个在一个查询中为我带来了服务。

    谢谢!!

    【讨论】:

      猜你喜欢
      • 2012-09-28
      • 1970-01-01
      • 1970-01-01
      • 2010-10-24
      • 1970-01-01
      • 2011-01-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多