Как получить максимальную производительность от LINQ, запрашивая несколько строк в таблице - PullRequest
1 голос
/ 18 ноября 2008

Моя цель - получить много строк из таблицы перевода. Я использую идентификатор, чтобы получить подмножество таблицы (скажем, 50 строк), затем я использую другой идентификатор для строк, которые я хочу из этого подмножества. Используя типизированные наборы данных, я делаю следующее, чтобы получить основной набор данных:

funderTextsDS.tbl_funderTextsDataTable fd = 
(funderTextsDS.tbl_funderTextsDataTable)(new funderTextsDSTableAdapters.tbl_funderTextsTableAdapter()).GetData();

Тогда для каждого значения, которое я хочу получить:

fd.Select("eng_code = '" + element + "' and funderID = '" + funderID + "'")[0]["funderText"].ToString();

Используя профилировщик ANTS для проверки кода, я обнаружил, что этот метод использовал около 170 мс при обновлении 10 страниц (220 обращений к fd.select ...)

Когда я переписал это в LINQ, для выполнения той же работы потребовалось более 2000 мс. Вот код LINQ, который я использовал:

IrmDatabaseContext irmDB = new IrmDatabaseContext();
irmDB.tbl_funderTexts.Single(f => f.funderID == funderId && f.eng_code == element).funderText;

У кого-нибудь есть хороший способ сделать это с помощью LINQ? Просматривая SQL Server Profiler, я увидел, что LINQ фактически генерирует один выбор для каждого полученного текста. (т.е. LINQ = 220 выбирает из базы данных, метод tableadapter = 10 выбирает)

Решение: Прочитав информацию в сети, я обнаружил, что Дэвид Б был на правильном пути, хотя цикл for отбросил меня на некоторое время. В любом случае, хитрость, как он сказал, состоит в том, чтобы использовать список, поскольку это фактически заставляет linq выполнять запрос к БД и кэшировать его локально. http://blogs.msdn.com/wriju/archive/2007/07/17/linq-to-sql-caching-the-query-execution.aspx.

Итак, мое решение закончилось так:

List<tbl_funderText> fd = (from tf in irmDB.tbl_funderTexts
                      where tf.funderID == (int)cpcrow.cpc_fundingPartnerID
                      select tf).ToList();

Тогда каждый раз, когда мне нужен элемент, который я делаю:

fd.Single(f => f.eng_code == element).funderText;

Анализируя с помощью ANTS, я обнаружил, что время было сокращено до 150 мс (примерно столько же, сколько у tableAdapter. Анализатор запросов SQL показывает, что SQL запускается только один раз.

Ответы [ 2 ]

1 голос
/ 18 ноября 2008

Ах, поэтому в методе TableAdapter вы извлекаете строки в память, а затем запрашиваете эти строки в памяти. Это легко сделать в LINQ.

myDataContext dc = new myDataContext();
List<FunderText> myList = myDataContext.tbl_funderTexts.ToList();

List<string> result1 = new List<string>();
foreach(var theValue in myValues)
{
  result1.Add(
    myList.First(f => f.funderID == theValue.funderId && f.eng_code == element).funderText
  );
}
0 голосов
/ 18 ноября 2008

Я не уверен, поможет ли это, но попробуйте использовать .where вместо .single. Что-то вроде этого:

var data = mDB.tbl_funderTexts.where(f => f.funderID == funderid && f.eng_code == element)
var fundertext = data.single().funderText
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...