我试图在与Entity Framework专门合作几年后自学NHibernate。我知道如何编写查询,我知道如何使用EF和lambda表达式编写代码,但将其转换为NHibernate会让我感到难过。
查询将写为:
SELECT fb.*
FROM foo f
INNER JOIN bar b ON f.fooid = b.fooid
INNER JOIN foobar fb ON b.barid = fb.barid
WHERE f.otherid = 1
基本上,我知道我的起始表(foo
)的一个键,我想返回第二个连接表(foobar
)中的所有匹配行。在EF,我会写:
public IEnumerable<foobar> GetFooBarInfo(int intFooID)
{
return db.foo.Include(f => f.bar)
.Include(fb => fb.bar.foobar)
.Where(f => f.otherentity.fooid == intFooID)
.Select(fb => fb.bar.foobar)
.ToList();
}
现在将其转换为NHibernate是我需要帮助的地方。我尝试了一些东西,其中没有一个我已经保存,但最新版本返回1行而不是7行。看起来它返回foobar
barid = 1
中的一行而不是barid
所有的fooid = 1
值。
public IEnumerable<foobar> GetFooBarInfo(int intFooID)
{
foo f = null;
bar b = null;
foobar fb = null;
return db.QueryOver<foo>(() => f)
.Where(fi => fi.otherentity.fooid == intFooID)
.Inner.JoinQueryOver(ba => ba.bar, () => b)
.Inner.JoinQueryOver(fbar => fbar.foobar, () => fb)
.Select(Projections.ProjectionList()
.Add(Projections.Property(() => fb.barid))
.Add(Projections.Property(() => fb.barname))
.Add(Projections.Property(() => fb.bardescription))
)
.TransformUsing(Transformers.AliasToBean<foobar>())
.List<foobar>();
}
我也意识到它并没有真正填充投影/变换。 barid
为0,barname
和bardescription
为空 - 这些显然在数据库中有值。
答案 0 :(得分:0)
我在foo
上尝试加入bar
和fooid
,但bar
有自己的主键foobarid
。一旦我打开了NHibernate的日志记录,我就可以看到生成了
查询不正确。它产生了:
SELECT fb.*
FROM foo f
INNER JOIN bar b ON f.fooid = b.foobarid
INNER JOIN foobar fb ON b.barid = fb.barid
WHERE f.otherid = 1
然后我意识到我需要包含bar
的父表,它是baz
才能使连接正确。但这意味着我需要制作地图
baz
包括:
.HasMany(x => x.bar).KeyColumn("fooid")
.HasMany(x => x.foobar).KeyColumn("barid")
然后更改QueryOver
以包含此附加表。这使结果计数正确,但仍然没有正确地投射到对象中 - 一切都是空的
直到我在每个Projection.Property()
添加了字符串别名:
public IEnumerable<foobar> GetFooBarInfo(int intFooID)
{
foo f = null;
bar b = null;
baz bz = null;
foobar fb = null;
return db.QueryOver<foo>(() => f)
.Where(fi => fi.otherentity.fooid == intFooID)
.Inner.JoinQueryOver(bb => bb.baz, () => bz)
.Inner.JoinQueryOver(ba => ba.bar, () => b)
.Inner.JoinQueryOver(fbar => fbar.foobar, () => fb)
.Select(Projections.ProjectionList()
.Add(Projections.Property(() => fb.barid), "barid")
.Add(Projections.Property(() => fb.barname), "barname")
.Add(Projections.Property(() => fb.bardescription), "bardescription")
)
.TransformUsing(Transformers.AliasToBean<foobar>())
.List<foobar>();
}