将IEnumerable转换为IQueryable的实体框架副作用

时间:2017-11-28 22:50:20

标签: c# entity-framework

这不是关于如何转换的问题。这是一个关于副作用的问题。让我们从我的理解开始:

  • IQueryable是生成SQL过程中的延迟集合。
  • IEnumerable是一个延迟集合,可以过滤SQL结果,但SQL生成已经完成。
  • T或List是具体的,无法在数据库中生成或过滤SQL

因此,我们通常从IQueryables开始,以及Where扩展正在生成SQL。

然后我们进入IEnumerables,查询仍然延迟,但我可以应用我希望添加的代码内过滤。 Query仍会返回IQueryable过滤器的所有结果,但Enumerable只会返回代码过滤的结果。

当使用像ToList,Single,First等具体调用执行Queryable或Enumerable时...那么我留下了Concrete对象。

因此,如果我使用Queryable,将其转换为Enumerable,我可以将其更改回Queryable吗?在什么情况下?如果我首先将过滤器链接到IEnumerable怎么办?伪代码示例:

var yesterdaysTacoOrders = GetOrdersForDate(yesterday);

public List<Order> GetOrdersForDate(DateTime someDate) 
{
    using (var context = new DbContext()) 
    {
        return GetOrderQuery(context, someDate)
                .Where(x => x.OrderType == OrderType.Retail).ToList();
    }
}

public IQueryable<Order> GetOrderQuery(DbContext context, DateTime someDate) 
{
    return GetOrderEnumerable(context, someDate)
            .Where(x => x.OrderName.Contains("Taco")).AsQueryable();
}

public IEnumerable<Order> GetOrderEnumerable(DbContext context, DateTime someDate) 
{
    return context.Set<Order>()
            .Where(x => x.Date == someDate).AsEnumerable();
}

实际执行的第一个代码是上面的最后一行,其中使用实体框架上下文来提取IQueryable,但返回IEnumerable。

其调用者(GetOrderQuery)接收IEnumerable,应用过滤器,但返回IQueryable。

ITS CALLER(GetOrdersForDate)接收IQueryable,应用过滤器,并使用ToList()执行。

哪些部分转换为SQL,哪些部分是按代码过滤的?什么是副作用?

0 个答案:

没有答案