Как я могу вернуть средство чтения данных при использовании Entity Framework 4?

#entity-framework #ado.net #entity-framework-4.1

#entity-framework #ado.net #entity-framework-4.1

Вопрос:

Я хочу определить запрос к базе данных с помощью LINQ и моего контекста EntityFramework, но я не хочу, чтобы возвращались объекты; Я хочу datareader!

Как я могу это сделать? Это для экспорта строк в CSV.

Приветствую, Ян.

Комментарии:

1. Почему бы просто не получить объекты и сериализовать их в CSV?

2. Я не знаю, сколько там будет объектов, поэтому datareader останавливает заполнение памяти сервера.

3. Немного оглядевшись, вы, возможно, не сможете легко добраться до него, существует метод ExecuteDbDataReader , но он защищен, поэтому вам, вероятно, не следует пытаться им завладеть. Если это делается не очень часто и / или если запрос не слишком дорогой, вы могли бы попробовать подкачать результаты вашего запроса, чтобы убедиться, что у вас не слишком много объектов в памяти одновременно.

Ответ №1:

Если вам это нужно, вы, скорее всего, делаете что-то неожиданное. Простая итерация по материализованному результату запроса должна быть тем, что вам нужно — это способ ORM. Если вам это не нравится, используйте SqlCommand напрямую.

DbContext API упрощен, и из-за этого он не содержит многих функций, доступных в ObjectContext API. Доступ к считывателю данных — один из них. Вы можете попробовать преобразовать DbContext в ObjectContext и использовать более сложный API:

 ObjectContext objContext = ((IObjectContextAdapter)dbContext).ObjectContext;
using (var connection = objContext.Connection as EntityConnection)
{
    // Create Entity SQL command querying conceptual model hidden behind your code-first mapping
    EntityCommand command = connection.CreateCommand();
    command.CommandText = "SELECT VALUE entity FROM ContextName.DbSetName AS entity";
    connection.Open();
    using (EntityDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess))
    {
        ...
    }
}
  

Но чистый ADO.NET способ намного проще и быстрее, потому что в первом примере все еще используется сопоставление запроса с SQL-запросом:

 using (var connection = new SqlConnection(Database.Connection.ConnectionString))
{
    SqlCommand command = connection.CreateCommand();
    command.CommandText = "SELECT * FROM DbSetName";
    connection.Open();
    using(SqlDataReader reader = command.ExecuteReader())
    {

    }
}
  

Комментарии:

1. «Если вам это нужно, вы, скорее всего, делаете что-то неожиданное». Я не думаю, что есть что-то особенно странное в запросе большого количества объектов для экспорта или для генерации электронных писем. ORM все еще может материализовывать объекты, но передавать их из базы данных в режиме чистого чтения данных. LLBLGen позволяет получить доступ к устройству чтения данных. llblgen.com/documentation/2.6/Using the generated code /…

Ответ №2:

Этот вопрос касается EF 4, но для любого другого пользователя с EF 6 или выше вы можете использовать метод расширения AsStreaming ().

http://msdn.microsoft.com/en-us/library/dn237204 (v = против 113).aspx

Комментарии:

1. Для всех, кто похож на меня и понятия не имеет, что делает AsStreaming (), вот единственная проходная ссылка, которую я смог найти для нее: entityframework.codeplex.com /… . Кажется, нигде нет другой документации.

2. В настоящее время этот метод устарел, и его вызов не имеет никакого эффекта, поскольку запросы LINQ передаются потоком по умолчанию. Я предполагаю, что это только для EF6, хотя. Вы все равно должны использовать ответ Ладислава для EF4.