NHibernate 是一种对象/关系映射器,因此如果要正确地提出“如何编写此查询”问题,您需要提供足够的信息,以便潜在的答复者能够理解以下三个内容的样子:
- NHibernate 实体类 (这是“对象”部分)
- 数据库表 (这是“关系”部分)
- 映射,无论是 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; }
public virtual IList<AccountProfile> Followers { get; set; }
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; }
}
...其中Followers和Following是多对多关系的两个相反方面。这对于大多数人来说应该足够了,以便能够填补空白并直观地理解表和映射的样子。
既然我们有了这个基础,让我们来处理查询。如果我们重写查询以使用连接而不是子查询,则您的查询将更容易处理:
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()
让我们把这个查询翻译成英文:"Select the list of newsfeeds belonging to all the people who are following account #1." 然而,我感觉你的意思是 "Select the list of newsfeeds belonging to all the accounts followed by account #1",这对我来说似乎更有用。在QueryOver中,它看起来像这样(用Followers替换Following)。
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的经验不如其他人丰富。
var result = from n in session.Query<NewsFeed>() where (from f in session.Query<Follower>() where f.AccountProfile.Id == 1 select f.Follower).Contains(n.AccountProfile) select n;
- FiroNewsFeed
、AccountProfile
和(如果有的话)Follow
类的代码?如果我们了解实体之间的关系,我们就可以更好地帮助你解决问题。 - Daniel Schilling