简体   繁体   English

从Entity Framework查询转换为NHibernate的问题

[英]Trouble transitioning from Entity Framework query to NHibernate

I am attempting to teach myself NHibernate after working exclusively with Entity Framework for a few years now. 在与Entity Framework一起专门工作了几年之后,我试图自学NHibernate。 I know how I would write the query, and I know how I would write the code with EF and lambda expressions, but translating that to NHibernate is stumping me. 我知道如何编写查询,也知道如何编写带有EF和lambda表达式的代码,但是将其翻译为NHibernate会让我很困扰。

The query would be written as: 该查询将被写为:

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

Basically, I know a key of my start table ( foo ), and I want to return all of the matching rows in the 2nd joined table ( foobar ). 基本上,我知道启动表的一个键( foo ),并且我想返回第二个联接表( foobar )中的所有匹配行。 In EF, I would write: 在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();
}

Now converting that to NHibernate is where I need help. 现在,我需要将其转换为NHibernate。 I have tried a few things, none of which I've saved, but the latest version returns 1 row instead of 7 rows. 我尝试了几件事,但都没有保存,但最新版本返回1行而不是7行。 It looks like it is returning the one row in foobar where barid = 1 instead of all barid values where fooid = 1 . 好像它在foobarbarid = 1一行,而不是在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>();
}

I also just realized that it isn't truly filling the projection/transform. 我还意识到它并没有真正填充投影/变换。 barid is 0 and barname and bardescription are null - these obviously have values in the database. barid为0, barnamebardescription为空-这些显然在数据库中具有值。

I was attempting to join foo and bar on fooid , but bar had its own primary key foobarid . 我试图在fooid上加入foobar ,但是bar有自己的主键foobarid Once I turned on logging for NHibernate, I could see the generated query was incorrect . 打开NHibernate的日志记录后,我可以看到生成的查询不正确 It was generating: 它正在生成:

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

So then I realized I needed to include the parent table for bar , which was baz in order to get the join right. 因此,我意识到我需要包括bar的父表,该表是baz以便正确连接。 But this meant I needed to make the map for baz include: 但这意味着我需要为baz制作地图,包括:

.HasMany(x => x.bar).KeyColumn("fooid")
.HasMany(x => x.foobar).KeyColumn("barid")

Then alter the QueryOver to include this additional table. 然后更改QueryOver以包括此附加表。 This got the result count right, but still wasn't projecting into the object properly - everything was null until I added the string alias on each Projection.Property() : 结果计数正确,但是仍然无法正确投影到对象中-一切都为空,直到我在每个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>();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM