Многие пытаются сравнить производительность 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.CallDetails
where 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." ..>.
Комментариев нет:
Отправить комментарий