У меня есть ситуация, когда определенный запрос linq, который выполняется для таблицы с многомиллионными строками, занимает слишком много времени. Я проанализировал вывод запроса linq и обнаружил, что он создает параметры для предложения where с использованием неправильного типа данных. Например, одно поле было определено в базе данных как Char (12), но параметр, с которым оно сравнивалось, был объявлен как NVarChar (12). После того, как я изменил запрос на использование Char вместо NVarChar, он работал менее чем за секунду, как и должен. Есть ли способ заставить linq to sql использовать правильный тип данных, как определено в файле .dbml для этого столбца? Я дважды проверил и определил его как DbType = "Char (12)" в файле контекста данных .dbml.
Как заставить linq использовать sql правильный тип данных для параметров sql?
Ответы (1)
Вы можете получить команду и напрямую сбросить типы параметров (в вашем случае на ansi-строку).
http://msdn.microsoft.com/en-us/library/system.data.linq.datacontext.getcommand.aspx http://msdn.microsoft.com/en-us/library/system.data.dbtype.aspx
Затем вы можете вызвать ExecuteReader для этой команды, получив в результате DbDataReader. Вы можете передать этот DbDataReader методу Translate вашего контекста данных, и он даст вам IEnumerable<T>
, который вы ожидаете от linq.
http://msdn.microsoft.com/en-us/library/bb534213.aspx
Проблема с производительностью вызвана тем, что параметр запроса имеет другой тип, чем индекс, выбранный оптимизатором запросов. Далее происходит преобразование всего индекса в тип параметра. Это выполняется каждый раз при отправке запроса - преобразование не откладывается для последующих запросов.
Обычно я наблюдаю такое поведение при отправке набора строк в базу данных:
//this query will get correct parameter type
db.Customers.Where(c => c.Name == "Bob")
//this query can get incorrect parameter type
List<string> names = new List<string>(){"Amy", "Bob"};
db.Customers.Where(c => names.Contains(c.Name));