我正在尝试使用nhibernate标准执行LEFT OUTER JOIN。我还有一个应用于我的查询的过滤器。
我遇到的问题是,如果连接结果为空,则过滤器会阻止左外连接正常工作。
作为一个非常简单的例子,我想要归还所有的音乐家,如果他们在一个乐队中,那么他们也是他们的乐队
NHibernate生成以下sql
SELECT this_.Name, band2_.Name
FROM Musicians this_
left outer join [Band] band2_
on this_.BandID = band2_.ID
WHERE (band2_.IsDeleted = 0)
如果他们不在乐队中,则不会返回音乐家。我想要的是像
SELECT this_.Name, band2_.Name
FROM Musicians this_
left outer join [Band] band2_
on this_.BandID = band2_.ID
WHERE this_.ID = 4894 /* @p3 */
(band2_.ID IS NULL OR band2_.IsDeleted = 0)
这是否可以使用nhibernate?
更新
var projections = new[]
{
Projections.Property("Musician.Name").As("MusicianName"),
Projections.Property("Band.Name").As("BandName")
};
return this.sessionProvider.GetSession().CreateCriteria<Musician>("Musician")
.CreateCriteria("Musician.Band", "Band", JoinType.LeftOuterJoin)
.SetProjection(projections)
.Add(Restrictions.Eq("Musician.ID", parameters.MusicianId))
.SetResultTransformer(Transformers.AliasToBean<MusicianDetailsResult>())
.UniqueResult<MusicianDetailsResult>();
过滤器使用FluentNHibernate定义
this.WithName(FilterName).WithCondition("IsDeleted = 0")
答案 0 :(得分:1)
我使用了建议的解决方法,并将过滤器上的useManyToOne
设置为false。此属性当前不在FluentNhibernate中,因此我只在ExposeConfiguration
foreach (var key in cfg.FilterDefinitions.Keys)
{
filter = cfg.FilterDefinitions[key];
cfg.FilterDefinitions[key] = new FilterDefinition(
filter.FilterName,
filter.DefaultFilterCondition,
filter.ParameterTypes, false);
}
答案 1 :(得分:0)
首先,如果你只是将Band作为参考映射到音乐家,那就容易多了:
public class MusicianDbMap : ClassMap<Musician>
{
public MusicianDbMap()
{
...
References(x => x.Band)
.Nullable()
.Not.LazyLoad(); // Or lazy load... either way
}
}
然后你可以运行一个简单的查询 - 这里是Linq-2-NHibernate:
Session.Linq<Musician>()
.Where(x => x.Band == null || !x.Band.IsDeleted)
.ToList();
其次,我不确定你的这句话:“如果他们不在一个乐队中,那将不会让音乐家回归”......我不确定这是否正确。左外连接应该返回所有行,无论它们是否在乐队中 - 你确定你没有在其他地方出错吗?