NHibernate LinqProvider / IQueryable:在 Where 子句中是不是支持 FirstOrDefault()?
Posted
技术标签:
【中文标题】NHibernate LinqProvider / IQueryable:在 Where 子句中是不是支持 FirstOrDefault()?【英文标题】:NHibernate LinqProvider / IQueryable: Is FirstOrDefault() supported inside a Where clause?NHibernate LinqProvider / IQueryable:在 Where 子句中是否支持 FirstOrDefault()? 【发布时间】:2012-10-09 14:50:29 【问题描述】:给定两个相似的类
public class Blog
public virtual int BlogId get; set;
public virtual IList<Comment> Comments get; set;
public class Comment
public virtual int CommentId get; set;
public virtual Blog Blog get; set;
public string Title get; set;
我很难使用以下语句:
session.Query<Blog>.Where(b => b.Comments.FirstOrDefault().Title.Contains("my title")));
抛出的错误是:
Antlr.Runtime.NoViableAltException
使用 .Any() 有效:
session.Query<Blog>.Where(b => b.Comments.Any(c => c.Title.Contains("my title")));
然而,这不是我想要的。实际上,这不是关于博客和评论,而是关于版本化实体。在它们的父实体的映射中,我按它们的版本号对它们的集合进行排序。我需要能够访问第一个条目才能获得最新版本。
【问题讨论】:
不支持因为FirstOrDefault()
、ToList()
等方法,它们将 IQueryable 完成为具体类型(原始类型、唯一实体和列表)。如果你调用这样的东西,你会得到一个异常,因为你仍然在执行的上下文中,是什么让你无法运行子查询。在这种情况下,您必须使用.Any
方法,因为它会在 SQL 语句内部生成一个子选择。
为了解决您的问题,您可以在您的存储库中添加一个方法来获取第一个带有 idBlog 的评论。
@Felipe Orani:这是复杂查询的一部分,为每个博客触发选择不会很好。一个技巧是将 FirstCommentId 属性添加到实体 Blog 并通过公式映射该属性(“Select Top 1 CommentId from ...”),然后执行 .Any(c=> c.CommentId == b.FirstCommentId && c.Title.Contains("我的标题")
【参考方案1】:
为什么不在 db 中预过滤并使用 linq to objects 最终过滤它?
var results = session.Query<Blog>()
.Where(b => b.Comments.Any(c => c.Title.Contains("my title")))
.AsEnumerable()
.Where(b => b.Comments[0].Title.Contains("my title")))
.ToList();
或者如果列表位置在评论中(不漂亮)
Map(x => x.Position, "listindexcolumn").ReadOnly();
var results = session.Query<Blog>()
.Where(b => b.Comments.Any(c => c.Position == 0 && c.Title.Contains("my title")))
.ToList();
或使用仅查询属性
Map(x => this.Position, "listindexcolumn").ReadOnly().Access.None();
var results = session.CreateCriteria<Blog>()
.CreateCriteria("Comments")
.Add(Restriction.Eq("Position", 0) && Restriction.Like("Title", "my title"))
.ToList<Blog>();
【讨论】:
以上是关于NHibernate LinqProvider / IQueryable:在 Where 子句中是不是支持 FirstOrDefault()?的主要内容,如果未能解决你的问题,请参考以下文章
Nhibernate学习教程-- 第一个NHibernate程序
NHibernate 2 + NHibernate.JetDriver + MS Access:如何访问表的“附件”字段