У меня следующий запрос LINQ-to-entity
IQueryable<History<T>> GetFirstOperationsForEveryId<T>
(IQueryable<History<T>> ItemHistory)
{
var q = (from h in ItemHistory
where h.OperationId ==
(from h1 in ItemHistory
where h1.GenericId == h.GenericId
select h1.OperationId).Min()
select h);
return q;
}
ItemHistory
- это общий запрос.Его можно получить следующим образом:
var history1 = MyEntitiySet1.Select(obj =>
new History<long>{ obj.OperationId, GenericId = obj.LongId });
var history2 = AnotherEntitiySet.Select(obj =>
new History<string>{ obj.OperationId, GenericId = obj.StringId });
В конце концов я хочу, чтобы универсальный запрос мог работать с любой коллекцией сущностей, конвертируемой в History<T>
.
.код не компилируется из-за сравнения GenericId во внутреннем запросе (оператор '==' не может быть применен к операндам типа 'T' и 'T').
Если я изменяю== до h1.GenericId.Equals(h.GenericId)
Я получаю следующее NotSupportedException
:
Невозможно привести тип 'System.Int64' к типу 'System.Object'.LINQ to Entities поддерживает только приведение типов примитивов Entity Data Model.
Я попытался выполнить группировку вместо подзапроса и объединить результаты.
IQueryable<History<T>> GetFirstOperationsForEveryId<T>
(IQueryable<History<T>> ItemHistory)
{
var grouped = (from h1 in ItemHistory
group h1 by h1.GenericId into tt
select new
{
GenericId = tt.Key,
OperationId = tt.Min(ttt => ttt.OperationId)
});
var q = (from h in ItemHistory
join g in grouped
on new { h.OperationId, h.GenericId }
equals new { g.OperationId, g.GenericId }
select h);
return q;
}
Он компилируется, потому что GenericIdпо сравнению с ключевым словом equals
, и он работает, но запрос с реальными данными слишком медленный (он выполнялся в течение 11 часов на выделенном сервере postgresql).
Существует возможность построить целое выражение для внешнегогде заявление.Но код был бы слишком длинным и неясным.
Есть ли какие-нибудь простые обходные пути для сравнения на равенство с обобщениями в LINQ-to-entity?