EF ObjectQuery <T>Контекст, параметры, свойства соединения, эквивалентные для DbSet <T> - PullRequest
2 голосов
/ 28 февраля 2012

В более ранних версиях Entity Framework мы смогли набрать Context из ObjectQuery, чтобы прочитать Parameters, Connection и т. Д., Как показано ниже:

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

1 Ответ

2 голосов
/ 01 марта 2012

Это хороший обходной путь, хотя я не думаю, что вы можете сделать его гораздо более применимым, чем у вас уже есть.

Несколько вещей, которые нужно иметь в виду:
- в зависимости от запроса EF, например если вы используете параметр Включить или нет, столбцы, возвращаемые в считывателе, могут не соответствовать свойствам типа T, который вы передаете.
- В зависимости от того, есть ли у вас наследование в вашей модели, буква T, которую вы передаете для перевода, не всегда может быть правильной материализацией для каждой возвращенной строки.
- После завершения задачи, возвращенной ExecuteReaderAsync, вам все равно придется извлекать каждую строку, что в зависимости от плана выполнения для запроса и задержки, которую вы получаете с сервером, потенциально также является операцией блокировки.

Асинхронная поддержка не приходит в EF в 5.0, но мы работали с другими командами, чтобы убедиться, что у нас есть все необходимые строительные блоки, включенные в .NET 4.5, и эта функция довольно высока в нашем списке приоритетов. Я призываю вас проголосовать за него на нашем сайте UserVoice .

...