История пошла в обратную сторону, и теперь проще найти, как выполнять запросы к БД с помощью LINQ, чем как это сделать старым добрым SQL. Помимо этого, в некоторых случая может неслабо сказаться разница в производительности, что я и предлагаю вам рассмотреть далее на конкретных примерах.

ОСWindows 7 SP1 x64
ЯзыкC# / .NET 4
IDEVisual Studio
БДMicrosoft SQL Server

Пара слов

LINQ очень удобен, с ним приятно работать, будь то LINQ to SQL или Entity Framework. Работает автодополнение с IntelliSense, всё видно прямо во время написания, не нужно смотреть в схему БД. Короче, все ништяки ORM.

Но есть вопрос производительности - это и не скрывается - что работа с БД через LINQ проигрывает в скорости обычным запросам SQL. У меня появилась такая задача: сделать выборку данных (id записи и одно поле), затем выполнить поиск по этому полю в другой базе и результат записать в ещё одно место. Записей в исходной таблице больше 50 000. Так вот, через LINQ это всё выполнялось довольно долго, примерно 2000 записей за 10 минут. Я решил проверить, как это будет на чистом SQL, и результат оказался что-то около 3000 записей в минуту. То есть, если свести в таблицу с равными значениями, то:

Язык Время Записей обработано
LINQ10 минут2 000
SQL30 000

Вот тут-то я и выпилил все эту линкушные свистелки из проекта.

Практика

Выполнять “голые” SQL запросы без LINQ достаточно просто.

Выполнение простого запроса

Обычный SELECT к таблице:

// сюда будем складывать полученные данные
Dictionary<long, string> infa = new Dictionary<long, string>();

// объявили соединение
using (SqlConnection sqlConn = new SqlConnection("Data Source=someserver;Initial Catalog=somecatalog;Integrated Security=True"))
// объявили команду (SQL-запрос)
using (SqlCommand cmd = new SqlCommand("SELECT id, name FROM sometable;", sqlConn))
{
	// открыли соединение
	sqlConn.Open();
	// выполнили команду, получили результат
	SqlDataReader reader = cmd.ExecuteReader();
	while (reader.Read()) // перебираем результат
	{
		// и сохраняем его в наш словарь
	    infa.Add((long)reader[0], (string)reader[1]);
	}
}

Выхов хранимой процедуры с параметрами

Нужно вызвать хранимую процедуру с двумя входными параметрами.

// объявили соединение
using (SqlConnection sqlConn = new SqlConnection("Data Source=someserver;Initial Catalog=somecatalog;Integrated Security=True"))
// объявили команду (SQL-запрос)
using (SqlCommand cmd = new SqlCommand("searchInfoByName", sqlConn))
{
	// вот это важный момент, если его не указать, то процедура не будет выполняться, выдавая ошибку про отсутствующие параметры
	cmd.CommandType = CommandType.StoredProcedure;
	// у нас 50 000 записей, а стандартный таймаут 30 секунд, нам некогда по столько ждать
	cmd.CommandTimeout = 5;
	// открыли соединение
	sqlConn.Open();

	// для каждой записи словаря, собранного ранее, выполнить хранимую процедуру
	foreach (var rec in infa)
	{
	    try // выполнять будем с перехватом исключений
	    {
	    	// добавление параметров к процедуре
	        cmd.Parameters.Add(new SqlParameter("@name", rec.Value));
	        cmd.Parameters.Add(new SqlParameter("@id", rec.Key));
	        // данные получать нам не нужно, только вызвать процедуру
	        cmd.ExecuteNonQuery();
	    }
	    catch (Exception ex) 
	    {
	        // тут какая-нибудь запись в журнал ошибок
	    }

	    // очищаем параметры для следующей итерации
	    cmd.Parameters.Clear();
	}
}

Ещё пара слов

Конечно, смотреть всегда надо исходя из ситуации. Один только этот случай не означает, что никогда и ни за что не надо использовать LINQ. Просто имейте в виду, что когда нужна производительность, то лучше не обвешивать работу с БД дополнительными фреймворками.