Бих искал да заредя Test
по id, включително всички свързани TestRuns
и всички Measurements
с помощта на DbContext/EntityFramework от MySql база данни.
Това е схемата на базата данни:
Какво опитах досега:
public class TestRepository : Repository<Test>, ITestRepository
{
public IQueryable<Test> GetTestComplete(int id)
{
return DbSet.Where(t => t.Id == id)
.Include(t => t.TestRuns.Select(tr => tr.Measurements));
}
}
За съжаление това отнема много време, за да завърши (около една минута за 1 тест/1 тест/15 000 измервания). Опитах се да разбера генерирания SQL код с помощта на програма за профилиране на заявки, но не можах да осмисля огромния чудовищен SQL израз.
Можете ли да се сетите за по-добър (т.е. по-бърз) начин за зареждане на данните чрез DbContext?
Актуализация
Друг опит, който също води до дълго време за зареждане:
public Test GetTestComplete(int id)
{
Test test = DbSet.Find(id);
DbContext.Entry(test).Collection(t => t.TestRuns).Load();
foreach (var testRun in test.TestRuns)
{
// next line takes a lot of time!
DbContext.Entry(testRun).Collection(tr=>tr.Measurements).Load();
}
return test;
}
Зареждането на измерванията отнема 84% от времето:
Това е съответният sql оператор за извличане на измерванията:
SELECT
Extent1.id,
Extent1.test_run_id,
Extent1.rss_dbm
FROM measurement AS Extent1
WHERE Extent1.test_run_id = :EntityKeyValue1
Копирах всеки от получените sql изрази (от трите DbContext
/DbSet
заявки) от профилиращия заявка в MySqlWorkbench и всеки за себе си работи много бързо. Сега съм още по-объркана...
Актуализация 2
Изолирах функцията GetTestComplete
(вижте по-горе) в единична единица/тест за производителност и все още отнема много време. Резултатът от програмата за профилиране на заявки показва, че отделните sql команди са много бързи, въпреки че завършването на целия тест отнема около 5 секунди. Объркването нараства...
DbSet.AsNoTracking()
. Мисля, че много време се поглъща от мениджъра на състоянието на обекта и коригирането на отношенията. Ако трябва да промените данни, мисля, че трябва да опитате да извлечете само това, което трябва да промените. - person Gert Arnold   schedule 12.12.2014DbSet.AsNoTracking()
ще свърши работа и ще намали времето за заявка на измерванията от 4 s на 400 ms. Но как да използвамAsNoTracking()
с тази заявкаDbContext.Entry(testRun).Collection(tr => tr.Measurements).Load();
? - person nabulke   schedule 12.12.2014