gpt4 book ai didi

c# - NHibernate:如何在没有延迟加载的情况下通过一个 sql 查询急切地获取带有子实体过滤器的子实体?

转载 作者:太空狗 更新时间:2023-10-29 21:34:18 25 4
gpt4 key购买 nike

我将 NHibernate 3.3.1 与 FluentNhibernate 1.3 一起用于数据层。

我有以下实体:

enter image description here

数据库图: enter image description here

我需要一种通过产品媒体的 MediaCategory 获取产品的方法。我希望 NHibernate 只向 db 发送一个查询并获取产品的所有子属性。

我希望 NHibernate 发送这样的查询:

declare @mediaCategoryId int = 13
select *
from Product p
inner join Media m on m.ProductId=p.Id
inner join MediaCategoryMedia mcm on mcm.MediaId=m.Id
inner join MediaCategory mc on mc.Id=mcm.MediaCategoryId
left join ProductSeller ps on ps.ProductId=p.Id
left join Seller s on ps.SellerId=s.Id
where mc.Id=@mediaCategoryId

我尝试了以下选项来解决这个挑战;

  1. session .QueryOver< ProductEntity >() ...
    我试过Inner.JoinQueryOver< .. >().Fetch.Eager ...但我无法获取所有子实体。

  2. session.CreateCriteria< ProductEntity >().SetFetchMode("",FetchMode.Eager) ...
    在这种情况下,延迟加载有效,我不想要延迟加载。如果我从映射中禁用延迟加载,NH 会发送大量查询。我想要的是使用一个获取所有子实体的查询进行预加载。

  3. session.Query< ProductEntity >().FetchMany(p=>p.MediaList).ThenFetchMany(m=>m.SellerList) ...
    在这种情况下,我无法创建别名来传递 mediaCategoryId 过滤器。相反,我使用了 .Where(x=>x.MediaList.Any(m=>m.CategoryList.Any(...)))生成的查询也不是最优的。

  4. (来自 session 中的 p.Query< ProductEntity >()
    来自 p.MediaList 中的 m
    来自 m.MediaCategoryList 中的 c
    其中 c.Id==23
    选择 p).Fetch(x=>x.MediaList);

    这也没有像我想要的那样工作..

  5. var hql=@"select p from ProductEntity as p join fetch p.MediaList as m join fetch m.MediaCategoryList as mc left join fetch p.SellerList as s where mc.Id=:catId ";
    这适用于 hql 中的“join fetch”。
    我需要这种情况的最佳实践,但是 Hql 才是王道。

    我们可以用 session.Query<>() 处理这种情况吗?或 session.CreateCriteria,QueryOver ?

最佳答案

直接翻译您的查询...

Media mediaAlias = null;
MediaCategory categoryAlias = null;

return session.QueryOver<Product>()
.JoinAlias(x => x.Medias, () => mediaAlias)
.JoinAlias(() => mediaAlias.Categories, () => categoryAlias)
.Fetch(x => x.Sellers).Eager
.Where(() => categoryAlias.Id == mediaCategoryId)
.List();

JoinAlias 默认执行内部连接,而 Fetch(...).Eager 执行左外部连接。 JoinAlias 允许我们通过媒体向下挖掘到类别,它也热切地获取数据。

请注意,此查询中的 Sellers 和 Medias 之间存在笛卡尔积。如果单个产品有 20 个媒体和 20 个卖家,则此查询将返回 20 * 20 = 400 行,这对于性能而言并不理想。您可以通过将媒体获取和卖家获取拆分为单独的查询来解决此问题,但使用 Future() 将它们一起批量处理到数据库,这意味着查询将返回 20 + 20 = 40 行。好多了。

此外,此查询不会返回与媒体关联的所有类别。如果您需要这个,那么您应该在 Exists 子查询中应用 mediaCategoryId 约束。

关于c# - NHibernate:如何在没有延迟加载的情况下通过一个 sql 查询急切地获取带有子实体过滤器的子实体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18334209/

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