meh*_*cek 6 c# nhibernate hql fluent-nhibernate c#-4.0
我使用NHibernate 3.3.1和FluentNhibernate 1.3进行数据层.
我有以下实体:
数据库图:
我需要一种方法来获取产品媒体的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
Run Code Online (Sandbox Code Playgroud)
我尝试了以下选项来解决这一挑战;
session .QueryOver< ProductEntity >()
...
我试过Inner.JoinQueryOver< .. >().Fetch.Eager
......但我无法获取所有子实体.
session.CreateCriteria< ProductEntity >().SetFetchMode("",FetchMode.Eager)
...
在这种情况下,延迟加载工作,我不想要lazyload.如果我从映射中禁用lazyload,NH会发送大量查询..我想要的是一个单一查询来获取所有子实体.
session.Query< ProductEntity >().FetchMany(p=>p.MediaList).ThenFetchMany(m=>m.SellerList)
...
在这种情况下,我无法创建传递mediaCategoryId过滤器的别名.相反,我使用了.Where(x=>x.MediaList.Any(m=>m.CategoryList.Any(...)))
,生成的查询也不是最佳的.
(来自p中的
会话.查询<ProductEntity>()from m in p.MediaList
from c in m.MediaCategoryList
where c.Id == 23
select p).Fetch(x => x.MediaList);
这也不像我想要的那样工作..
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();
Run Code Online (Sandbox Code Playgroud)
JoinAlias
默认情况下执行内连接,并Fetch(...).Eager
执行左外连接. JoinAlias
允许我们通过媒体挖掘类别,并且还急切地获取数据.
请注意,在此查询中,卖家和媒体之间存在笛卡尔积.如果单个产品上有20个Medias和20个Sellers,则此查询将返回20*20 = 400行,这对性能而言并不理想.您可以通过将媒体提取和卖方提取分成单独的查询来解决此问题,但是使用一次往返数据库将它们一起批处理Future()
,这意味着查询将返回20 + 20 = 40行.好多了.
此外,此查询不会返回与媒体关联的所有类别.如果需要,则应mediaCategoryId
在Exists子查询中应用约束.
归档时间: |
|
查看次数: |
18014 次 |
最近记录: |