无法从实体框架查询过渡到NHibernate

时间:2014-11-21 03:28:34

标签: c# mysql asp.net-mvc-4 nhibernate fluent-nhibernate

我试图在与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,barnamebardescription为空 - 这些显然在数据库中有值。

1 个答案:

答案 0 :(得分:0)

我在foo上尝试加入barfooid,但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>();
}