У меня есть метод, который принимает делегата и запускает его на объекте DbContext.Local и, если он равен нулю, пытается найти его в базе данных, как указано ниже.
public static T FirstOrDefaultInLocalOrDb<T>(this DbSet<T> myTable, Func<T, string, bool> criteria, string input) where T : class
{
var output = myTable.Local.Where(o => criteria((T)o, input)).FirstOrDefault();
if (output == null)
{
Expression<Func<T, bool>> predicate = (u) => criteria(u, input);
output = myTable.Where(predicate.Compile()).FirstOrDefault();
}
return output;
}
99% времени он находит его в локальной сущности и не нуждается в переходе в БД.
В другой части моей программы эта строка вызывает этот метод тысячи раз, каждый раз с уникальным HomeId.
var currHouse = db.Houses.FirstOrDefaultInLocalOrDb2(delegate(House h, string value) { return h.AllHomesID == value; }, HomeId);
Я провел некоторое тестирование производительности и понял, что этот метод работает очень медленно, и я думаю, что это потому, что он должен компилировать делегат каждый раз, когда он выполняется.
Этот метод используется и в других местах, поэтому я должен оставить его в общем роде, но мне было интересно, так как эта строка по сути передает ему один и тот же делегат каждый раз, просто с другим входным значением, возможно ли это каким-то образом предварительно скомпилировать делегат, чтобы метод не нуждался в компиляции делегата каждый раз?
UPDATE
Я написал эту неуниверсальную версию метода, которую, я думаю, я пытаюсь заставить сделать свой оригинальный метод, просто обобщенным способом. Этот метод, казалось, работал намного быстрее. Используя System.Diagnostic.Stopwatch, старый метод работал около 100 мс, а этот - около 7 мс.
public static House FirstOrDefaultAllHomesIdInLocalOrDb(this DbSet<House> myHouseTable, string allHomesId)
{
var output = myHouseTable.Local.Where(o => o.AllHomesID == allHomesId).FirstOrDefault();
if (output == null)
{
output = myHouseTable.Where(o => o.AllHomesID == allHomesId).FirstOrDefault();
}
return output;
}