#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.