NHibernate 是一个对象/关系映射器,因此要正确提出“我如何编写此查询”问题,您需要提供足够的信息,以便潜在的回答者能够理解这三件事的样子:
- NHibernate 实体类(这是 Object 部分)
- 数据库表(这是关系部分)
-
映射,无论是 HBM.XML、FluentNH 等。
假设您的实体如下所示:
public class AccountProfile
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual IList<NewsFeed> NewsFeeds { get; set; }
/// <summary>
/// People following me.
/// </summary>
public virtual IList<AccountProfile> Followers { get; set; }
/// <summary>
/// People I am following.
/// </summary>
public virtual IList<AccountProfile> Following { get; set; }
}
public class NewsFeed
{
public virtual int Id { get; set; }
public virtual AccountProfile AccountProfile { get; set; }
public virtual string Name { get; set; }
}
... 追随者和追随者是多对多关系的对立面。对于大多数人来说,这应该足以填空并直观地了解表格和映射的样子。
现在我们有了这个基础,让我们来处理查询。如果我们重写它以使用连接而不是子查询,您的查询将更容易处理:
select newsfeed.*
from
newsfeed
inner join follow
on newsfeed.AccountProfileID = follow.FollowerID
where follow.AccountProfileID='1'
这个查询在行为上应该与原始查询完全相同,更符合关系数据库的思维方式,并且可能更高效一些。
等效的 NHibernate QueryOver(我的首选查询 API)查询如下所示:
AccountProfile accountProfileAlias = null;
AccountProfile followingAlias = null;
var feeds = session.QueryOver<NewsFeed>()
.JoinAlias(x => x.AccountProfile, () => accountProfileAlias)
.JoinAlias(() => accountProfileAlias.Following, () => followingAlias)
.Where(() => followingAlias.Id == 1)
.List();
让我们将此查询翻译成英文:“选择属于所有关注帐户 #1 的人的新闻源列表。” 但是,我感觉您的意思是 “选择属于所有帐户的新闻源列表,后跟帐户 #1",在我看来这更有用一些。在 QueryOver 中,看起来像这样(将关注替换为关注者)。
AccountProfile accountProfileAlias = null;
AccountProfile followerAlias = null;
var feeds = session.QueryOver<NewsFeed>()
.JoinAlias(x => x.AccountProfile, () => accountProfileAlias)
.JoinAlias(() => accountProfileAlias.Followers, () => followerAlias)
.Where(() => followerAlias.Id == 1)
.List();
如果其他人想尝试使用 NHibernate 的 LINQ 提供程序,也就是 session.Query,请随意,但我个人对该 API 没有太多经验。