EF 对象查询<T>上下文、参数、连接属性等效于 DbSet<T>



在早期版本的实体框架中,我们能够访问ObjectQuery中的Context,以便读取ParametersConnection等,如下所示:

var query = (ObjectQuery<T>)source;
cmd.Connection = (SqlConnection)((EntityConnection)query.Context.Connection).StoreConnection;
cmd.Parameters.AddRange(
    query.Parameters.Select(x => new SqlParameter(
        x.Name, x.Value ?? DBNull.Value)
    ).ToArray()
);

当我查看DbSet<T>对象时,我找不到任何等价的对象。我在这里的目的是创建扩展,它将操作查询并从中获得结果

下面是一个例子:http://philsversion.com/2011/09/07/async-entity-framework-queries

或者我应该为DbContext类编写扩展并使用Set方法吗?

知道吗?

编辑

以下是我到目前为止所做的。到目前为止基本实施,但肯定还没有准备好生产。对此有什么建议吗?

public static async Task<IEnumerable<T>> QueryAsync<T>(this DbContext @this, System.Linq.Expressions.Expression<Func<T, bool>> predicate = null)
    where T : class {
        var query = (predicate != null) ? @this.Set<T>().Where(predicate) : @this.Set<T>();
        var cmd = new SqlCommand();
        cmd.Connection = (SqlConnection)(@this.Database.Connection);
        cmd.CommandText = query.ToString();
        if (cmd.Connection.State == System.Data.ConnectionState.Closed) { 
            cmd.Connection.ConnectionString = new SqlConnectionStringBuilder(cmd.Connection.ConnectionString) {
                AsynchronousProcessing = true
            }.ToString();
            cmd.Connection.Open();
        }
        cmd.Disposed += (o, e) => {
            cmd.Clone();
        };
        var source = ((IObjectContextAdapter)@this).ObjectContext.Translate<T>(
            await cmd.ExecuteReaderAsync()
        );
        return source;
}

这是一个很好的解决方法,尽管我认为您无法使它比现有的更普遍地适用。

需要记住的几件事:
-根据EF查询,例如,如果您是否使用Include,读取器中返回的列可能与您正在传递的类型T中的属性不匹配
-根据您的模型中是否有继承,您传递给翻译的T可能并不总是对返回的每一行都是正确的
-ExecuteReaderAsync返回的任务完成后,您仍然需要检索每一行,这取决于查询的执行计划和服务器的延迟,这可能也是一个阻塞操作。

在5.0中,EF没有提供异步支持,但我们与其他团队合作,确保.NET 4.5中包含了所有必要的构建块,并且该功能在我们的优先级列表中非常高。我鼓励您在我们的UserVoice网站上投票支持它。

最新更新