EF ObjectQuery< T>上下文,参数,等价于DbSet< T> [英] EF ObjectQuery<T> Context, Parameters, Connection properties equivalent on DbSet<T>

查看:142
本文介绍了EF ObjectQuery< T>上下文,参数,等价于DbSet< T>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在早期版本的Entity Framework中,我们可以从 ObjectQuery 中获取上下文,以便阅读参数连接等如下:

In the earlier versions of Entity Framework, we were able to reach the Context out of ObjectQuery in order to read Parameters, Connection, etc. as below:

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> 对象,我无法找到任何等同于此。我的目的是创建扩展,它将操纵查询并从中获取结果。

When I look at the DbSet<T> object, I am unable to find any equivalent of this. My purpose here is to create extensions which will manipulate the query and get the result out of it.

这是一个实例: http://philsversion.com/2011/09/07/async-entity-framework-queries

或者我应该写扩展名 DbContext 类,并使用设置方法?

Or should I write the extension for DbContext class and work with Set method?

任何想法?

修改

这是我迄今为止所做的。到目前为止基本实施但肯定还没有准备生产。任何有关这方面的建议?

Here is what I did so far. Basic implementation so far but certainly not ready for production. Any suggestions on this?

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;
}


推荐答案

这是一个很好的解决方法,虽然我不认为你可以比现有的更普遍适用。

This is a nice workaround, although I don't think you can make it much more generally applicable than what you already have.

需要注意的几件事:

- 根据EF查询,例如如果您使用包含,则阅读器中返回的列可能与要传递的类型T中的属性不匹配。

- 根据您在模型中是否具有继承,您传递的T

- 在执行ExecuteReaderAsync返回的任务完成后,您仍然必须检索每一行,这取决于查询的执行计划,并且您使用服务器的延迟可能也是阻塞操作。

A few things to keep in mind:
- Depending on the EF query, e.g. if you are using Include or not, the columns returned in the reader might not match the properties in the type T you are passsing.
- Depending on whether you have inheritance in your model, the T that you pass to translate may not always be the right thing to materialize for every row returned.
- After the task returned by ExecuteReaderAsync completes, you still have to retrieve each row, which depending on the execution plan for the query and the latency you are getting with the server is potentially also a blocking operation.

在5.0中不支持异步支持,但是我们与其他团队合作,确保我们拥有.NET 4.5中包含的所有必要构建块,并且功能非常简单我们的优先级列表高。我鼓励你在我们的UserVoice网站上投票

Async support is not coming to EF in 5.0 but we worked with other teams to make sure we have all the necessary building blocks included in .NET 4.5 and the feature is pretty high in our priority list. I encourage you to vote for it in our UserVoice site.

这篇关于EF ObjectQuery&lt; T&gt;上下文,参数,等价于DbSet&lt; T&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆