【问题标题】:Build up IQueryable based on method parameters基于方法参数构建 IQueryable
【发布时间】:2013-03-19 04:24:12
【问题描述】:

我有一个类似于下面的 API 方法。

是否可以附加 IQueryable,以便最终查询具有执行 where 语句的项目列表,或者我应该使用 SqlQuery 属性并构建原始 SQL 字符串。

    public IEnumerable<Message> GetMessagesFromApi(DateTime? dateFrom = null, DateTime? dateTo = null, int flag = -1, int messageType = 1, bool media =false)
    {
        if (dateFrom == null)
            dateFrom = DateTime.MinValue;

        if (dateTo == null)
            dateTo = DateTime.MaxValue;

        IQueryable<Message> query = null;


        query = db.Messages.Where(x => x.Created >= dateFrom && x.Created <= dateTo);


        if (flag >= 0)
        {
            //Append the where statement on dates to now include Flag
            query = query.Where(x => x.Flag == flag);
        }

       //Here it should execute against Where date >= and date <= and flag = 1
    }

【问题讨论】:

    标签: c# .net entity-framework generics iqueryable


    【解决方案1】:

    是否可以附加 IQueryable,以便最终查询具有执行 where 语句的项目列表。

    是的。您的代码应该可以正常工作。如果你想为结果构建一个IEnumerable&lt;Message&gt;,你只需要执行这个。

    //Here it should execute against Where date >= and date <= and flag = 1
    return query.ToList();
    

    请注意,您可以使用AsEnumerable(),甚至直接返回query(因为IQueryable&lt;T&gt; 实现了IEnumerable&lt;T&gt;),但是如果用户多次枚举您的结果,这将导致问题,因为每次枚举都会命中数据库。

    我个人会这样写:

    public IEnumerable<Message> GetMessagesFromApi(DateTime? dateFrom = null, DateTime? dateTo = null, int flag = -1, int messageType = 1, bool media =false)
    {
        IQueryable<Message> query = db.Messages;
    
        if(dateFrom.HasValue)
            query = query.Where(x => x.Created >= dateFrom);
        if(dateTo.HasValue)
            query = query.Where(x => x.Created <= dateTo);
        if(flag >= 0)
            query = query.Where(x => x.Flag == flag);
        // others as needed, such as media...
    
        return query.ToList();
    }
    

    【讨论】:

    • 我用的是EF,可以用return AsEnumerable()
    • @Jon 是的,虽然使用AsEnumerable(),如果调用者枚举它两次,它会命中数据库两次...
    • 啊好的,谢谢,然后会返回一个列表。通过查看代码,似乎每次未附加查询都会被覆盖
    • @Jon 看看我的更新 - 查询将成为一个新查询,在旧查询后面附加了“Where”子句,因为它正在执行 query = query.Where..
    猜你喜欢
    • 2016-06-09
    • 1970-01-01
    • 1970-01-01
    • 2012-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-13
    • 2020-11-11
    相关资源
    最近更新 更多