gpt4 book ai didi

nhibernate - 使用NHibernate 3.0.0时要对抗笛卡尔乘积(x-join)

转载 作者:行者123 更新时间:2023-12-03 08:47:31 25 4
gpt4 key购买 nike

我数学不好,但是我知道cartesian product是什么。
这是我的情况(简体):

public class Project{
public IList<Partner> Partners{get;set;}
}
public class Partner{
public IList<PartnerCosts> Costs{get;set;}
public IList<Address> Addresses{get;set;}
}
public class PartnerCosts{
public Money Total{get;set;}
}
public class Money{
public decimal Amount{get;set;}
public int CurrencyCode{get;set;}
}
public class Address{
public string Street{get;set;}
}

我的目标是有效地加载整个项目。

问题当然是:
  • 如果我想急于加载合作伙伴及其成本,查询将返回gaxillion行
  • 如果我延迟加载Partner.Costs,db会收到垃圾邮件请求(比第一种方法快一点)

  • 如我所读,常见的解决方法是使用MultiQueries,但我有点不明白。
    所以我希望通过这个确切的例子来学习。

    如何有效加载整个项目?

    P.s.我正在使用NHibernate 3.0.0。
    请不要使用hql或字符串标准的api方法发布答案。

    最佳答案

    好的,我为自己写了一个反射(reflect)您的结构的示例,它应该可以工作:

    int projectId = 1; // replace that with the id you want
    // required for the joins in QueryOver
    Project pAlias = null;
    Partner paAlias = null;
    PartnerCosts pcAlias = null;
    Address aAlias = null;
    Money mAlias = null;

    // Query to load the desired project and nothing else
    var projects = repo.Session.QueryOver<Project>(() => pAlias)
    .Where(p => p.Id == projectId)
    .Future<Project>();

    // Query to load the Partners with the Costs (and the Money)
    var partners = repo.Session.QueryOver<Partner>(() => paAlias)
    .JoinAlias(p => p.Project, () => pAlias)
    .Left.JoinAlias(() => paAlias.Costs, () => pcAlias)
    .JoinAlias(() => pcAlias.Money, () => mAlias)
    .Where(() => pAlias.Id == projectId)
    .Future<Partner>();

    // Query to load the Partners with the Addresses
    var partners2 = repo.Session.QueryOver<Partner>(() => paAlias)
    .JoinAlias(o => o.Project, () => pAlias)
    .Left.JoinAlias(() => paAlias.Addresses, () => aAlias)
    .Where(() => pAlias.Id == projectId)
    .Future<Partner>();

    // when this is executed, the three queries are executed in one roundtrip
    var list = projects.ToList();
    Project project = list.FirstOrDefault();

    我的类(class)名称不同,但结构完全相同。我替换了名字,希望没有错别字。

    说明:

    联接需要别名。我定义了三个查询来加载所需的 ProjectPartnersCosts以及 PartnersAddresses。通过使用 .Futures(),我基本上告诉NHibernate在实际需要结果的那一刻,使用 projects.ToList()在一次往返中执行它们。

    这将导致三个SQL语句确实在一次往返中执行。这三个语句将返回以下结果:
    1)与您的项目一排
    2)与合作伙伴及其成本(和资金)共x行,其中x是项目合作伙伴的成本总数
    3)与合作伙伴及其地址的y行,其中y是项目合作伙伴的地址总数

    您的数据库应返回1 + x + y行,而不是x * y行,这将是笛卡尔积。我确实希望您的数据库实际支持该功能。

    关于nhibernate - 使用NHibernate 3.0.0时要对抗笛卡尔乘积(x-join),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5266180/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com