首页 问答 LINQ 中重用 Expression<Func<Blog, bool>> 的问题
问题详情

在下面的 C# 代码中针对 Blog 实体定义了 Expression<Func<Blog, bool>> (PublicSpec 方法部分)

public static class BlogsSpecs
{
    extension(IQueryable<Blog> blogs)
    {
        public IQueryable<Blog> Public()
            => blogs.Where(PublicSpec());
    }
    public static Expression<Func<Blog, bool>> PublicSpec()
        => b => b.Flag.HasFlag(ConfigurationFlag.IsPrivated) == false;
}

请问在 BlogPost 的导航属性 Blog 中如何使用这个表达式?

public static class BlogPostSpecs
{
    extension(IQueryable<BlogPost> posts)
    {
        public IQueryable<BlogPost> BlogIsPublic()
          => posts.Where(p => p.BlogSite); // 如何调用 BlogsSpecs.PublicSpec()
    }
}

回答

通过 deepseek 的回答解决了,需要将 p => p.BlogSitePublicSpec() 组合成一个新的表达式才行

public IQueryable<BlogPost> BlogIsPublic()
{
    Expression<Func<BlogPost, Blog>> blogSelector = p => p.Blog;
    var postFilter = ExpressionCombiner.Compose(BlogsSpecs.PublicSpec(), blogSelector);
    return posts.Where(postFilter);
}

ExpressionCombiner 的实现如下

public static class ExpressionCombiner
{
    public static Expression<Func<T, bool>> Compose<T, TProp>(
        Expression<Func<TProp, bool>> predicate,
        Expression<Func<T, TProp>> selector)
    {
        var param = selector.Parameters[0];
        var body = new ParameterReplacer(selector.Body).Visit(predicate.Body);
        return Expression.Lambda<Func<T, bool>>(body, param);
    }

    private class ParameterReplacer(Expression replacement) : ExpressionVisitor
    {
        protected override Expression VisitParameter(ParameterExpression node)
        {
            return replacement;
        }
    }
}

版权:言论仅代表个人观点,不代表官方立场。转载请注明出处:https://www.stntk.com/question/2530.html

发表评论
暂无评论

还没有评论呢,快来抢沙发~

点击联系客服

在线时间:8:00-16:00

客服QQ

70068002

客服电话

400-888-8888

客服邮箱

70068002@qq.com

扫描二维码

关注微信公众号

扫描二维码

手机访问本站