【问题标题】: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("我的标题")

标签: .net linq nhibernate orm fluent-nhibernate


【解决方案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>();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-21
    • 1970-01-01
    • 2011-09-03
    • 2013-02-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多