EF使用SQLquery作为输入延迟执行

时间:2017-10-26 17:13:48

标签: entity-framework linq

我试图通过将初始sql作为输入来获取具有EF的实体。 我尝试了context.Entities.SQLQuery方法但是当我需要IQueriable时会返回一个DBSet。

我了解到我无法将DBSet转换为IQueryable,因为第一个已经是数据的结果,而第二个是"查询"的结果的容器。 (已执行或未执行)。如果我错了,请纠正我:)

所以我认为当我编写以下lambda时,我会得到结果查询:

db.MyTable.Where(x => x.id == "123")

变为:

SELECT * FROM myTable WHERE id = '123'

有了这个,我想如果我可以直接设置我的查询而无需设置我的lambda ...

这是一个选择吗?

还是另类?

谢谢!

1 个答案:

答案 0 :(得分:0)

有点不清楚你的意思:

  

我正在尝试使用具有初始sql作为输入的EF实体。

我解释这一点,因为你有一个SQL语句作为某种东西的输入,并且你想得到一个具有这个语句的实体框架实体(无论有什么语句意味着)?不可理解!

  

我了解到我无法将DBSet转换为IQueryable,因为   第一个(DbSet)已经是数据的结果,而第二个(IQueryable)是"查询结果的容器"

不会!

每个DbSet<T>实现IQueryable<T>,这意味着如果您有类DbSet<t>的对象,则此对象实现IQueryable<T>的所有功能。仅使用此IQueryable不会执行查询。只有在请求时,查询才会执行一次序列的第一个元素。

using (var dbContext = new MyDbcontext())
{
    var result = dbContext.MyItems
        .Where(item => ...)
        .Select(item => new
        {
             X = item.Property1,
             Y = item.Property2,
             ...
        };

在此之前,不会询问序列的第一个元素,查询尚未执行。不需要与数据库进行通信(创建dbContext对象除外)

仅当您使用ToList()Count()First()Max()等执行功能时,才会执行查询。

您可以检查一下,因为如果您在使用块之后执行这些功能,则会出现异常:

<强>错误     IQueryable largeItems;     使用(var dbContext = new MyDbcontext())     {         largeItems = dbContext.MyItems             .Where(item =&gt; item.Size&gt; 1000);         //查询尚未执行     }     int nrOfLargeItems = largeItems.Count();     //异常,在释放dbContext后执行的查询

<强>正确     int nrOfLargeItems;     使用(var dbContext = new MyDbcontext())     {         var largeItems = dbContext.MyItems             .Where(item =&gt; item.Size&gt; 1000);         //查询尚未执行

    nrOfLargeItems = largeItems.Count();
    // the query is performed
}

结论:dbContext中DbSet<T>的用户可以使用DbSet<T>,就像它是IQueryable<T>一样,在执行任何需要第一个的函数之前,查询将不会被执行查询的元素。

这包括JoinGroupByOrderBy等复杂功能。您可以识别这些功能,因为MSDN将以下内容添加到备注部分

  

此方法通过使用延迟执行来实现。立即返回值是一个对象,它存储执行操作所需的所有信息。在通过直接调用其GetEnumerator方法或使用foreach枚举对象之前,不会执行此方法表示的查询。