【问题标题】:How to structure a partially dynamic LINQ statement?如何构造部分动态的 LINQ 语句?
【发布时间】:2011-05-25 04:50:40
【问题描述】:

我目前在我的存储库中有这样的方法:

    public int GetMessageCountBy_Username(string username, bool sent)
    {
        var query = _dataContext.Messages.AsQueryable();

        if (sent)
            query = query.Where(x => x.Sender.ToLower() == username.ToLower());
        else
            query = query.Where(x => x.Recipient.ToLower() == username.ToLower());

        return query.Count();
    }

它目前基于 sent 布尔值构建两个查询之一。这是执行此操作的最佳方法,还是有办法在查询本身中执行此操作?如果sent 等于真,我想检查x.Sender 是否等于username。但是我想检查x.Recipient是否等于username如果sent等于false。

然后我希望这个 LINQ 表达式在 Entity Framework 中转换为 SQL,我相信它正在这样做。

我只是想避免重复尽可能多的代码。

【问题讨论】:

    标签: c# sql linq entity-framework


    【解决方案1】:

    你可以这样做:

    public int GetMessageCountBy_Username(string username, bool sent)
     {
         Func<Message, string> userSelector = m => sent ? m.Sender : m.Recipient;
         var query =
         _dataContext.Messages.AsQueryable()
         .Where(x => userSelector(x).ToLower() == username.ToLower());
         return query.Count();
     } 
    

    因此选择正确的用户(发件人或收件人)在 linq 部分之前完成,避免您重复两次。

    【讨论】:

    • 太棒了!这更有意义。谢谢。
    • 我确实稍微修改了函数。 lambda 声明必须在 内联 IF 语句之前。
    • 看起来我在这里一直在接受答案。我应该先测试一下。这绝对有效,但不适用于 IQueryable。表达式树应该被翻译成 SQL 表达式。这意味着此 LINQ 语句不能调用另一个函数,所有相关数据必须包含在表达式中,SQL 翻译才能工作。 A .ToList() 将使其工作,但会牺牲在数据源中执行查询的能力。不过感谢您的回答!
    • 不能这样做实在是太可惜了。我非常喜欢代码看起来多么简单,但我不能牺牲将繁重的工作(即分页和排序)传递给 SQL Server :(
    • 哦,对不起,我确实错过了这一点。太糟糕了。 :-( 我不熟悉 IQueryable 并且我没有怀疑这个限制。但可能还有希望:如果你将 Func 更改为另一种类型,更接近纯的想法lambda ?(不幸的是,对于我不熟悉的东西,表达方式或类似的东西,不能更精确......?)
    【解决方案2】:

    是的,我相信这是正确的做法。因为无需重复整个查询部分即可轻松创建复杂查询。

    您关于翻译为 SQL 的想法也是正确的。但请注意,这是在请求数据或聚合时完成的。在您的情况下,当您调用 Count() 时,将生成并执行 SQL。

    【讨论】:

    • 太棒了。是的,只要在构建完整查询后执行它就可以了。我不喜欢在我的存储库中返回IQueryable&lt;T&gt;。我更喜欢为我的存储库提供比常规存储库做更多工作的更详细的方法。这样以后就不会出现延迟加载问题了:)
    猜你喜欢
    • 2013-06-06
    • 1970-01-01
    • 1970-01-01
    • 2018-10-18
    • 2020-01-19
    • 2013-12-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多