Многие пытаются сравнить производительность Entity Framework с чистым SQL. В любом случае запрос выполненный с помощью прямого SQL запроса будет быстрее чем использование LINQ хотя бы за счет маппинга полей.
Но эту разницу можно сократить до минимума. В EF 4.0 Linq запрос компилируются (разбираются) каждый раз когда к ним обращаются. Сама по себе эта операция дорогостоящая и мы должны от нее избавиться.
Делается это с помощью класса
Класс CompiledQuery имеет статический метод Compile, параметром которому идет выражение Linq. Результатом этой функции является делегат. Его и вызываем когда нужно получить данные через запрос.
Пример:
Особенности:
К сожалению такую штуку скомпилировать не удастся:
потому что "Only scalar parameters (such as Int32, Decimal, and Guid) are supported." ..>.
Но эту разницу можно сократить до минимума. В EF 4.0 Linq запрос компилируются (разбираются) каждый раз когда к ним обращаются. Сама по себе эта операция дорогостоящая и мы должны от нее избавиться.
Делается это с помощью класса
CompiledQueryКласс CompiledQuery имеет статический метод Compile, параметром которому идет выражение Linq. Результатом этой функции является делегат. Его и вызываем когда нужно получить данные через запрос.
Пример:
//делегат, с помощью которого будет вызываться наш запрос
Func <telephonyEntities1, int, List<int>, IQueryable<CallComment > _compiledCallCommentsGet = null;
public List CallCommentsGet(CallDetail callDetail) { if (callDetail == null) throw new ArgumentNullException("callDetail", "callDetail не должен быть null"); if (callDetail.id <= 0) throw new ArgumentException("callDetail.ID", "callDetail должен иметь ID");
List list = null; var context = GetSqlConnection();//Смотрим создавали ли мы уже скомпилированный linq запрос if (_compiledCallCommentsGet == null) {//сам процесс создания делегата _compiledCallCommentsGet = CompiledQuery.Compile<telephonyEntities1, int, List<int>, IQueryable<CallComment > ( (ctx, id) => from c in ctx.CallComments where c.CallDetail.id == callDetail.id orderby c.dateWhen descending select c); }//вызываем linq запрос через наш делегат list=_compiledCallCommentsGet.Invoke(context, callDetail.id).ToList(); return list;
}Особенности:
К сожалению такую штуку скомпилировать не удастся:
from cd in context.CallDetailswhere cd.Call.DateWhen >= dateTimeFrom && cd.Call.DateWhen < dateTimeTo && (listOpInt.Any() == false || listOpInt.Contains(cd.Call.Operator.id))select cdпотому что "Only scalar parameters (such as Int32, Decimal, and Guid) are supported." ..>.
Комментариев нет:
Отправить комментарий