Как стать автором
Обновить

Комментарии 13

У меня в проекте такой код работает нормально:

public static IQueryable<T> Range<T>(this IDbSet<T> set, HashSet<long> ids) where T : EntityBase
{
	return set.Where(x => ids.Contains(x.Id));
}


Что если вместо интерфейса использовать абстрактный класс?
Попробовал для интереса не интерфейс, а базовый класс — та же фигня, только теперь в ошибке написано, что не может привести объект к базовому классу.
Ваш пример также не работает, единственное отличие, я дописал материализацию запроса в массив:
public static T[] Range<T>(this IDbSet<T> set, HashSet<long> ids) where T : EntityBase
{
	return set.Where(x => ids.Contains(x.Id)).ToArray();
}
Так, а давайте ради интереса сделаем

return ((IQueryable)DbSet<TEntity>()).FirstOrDefault(x => x.Id == "id");
Ну, так компилятор не даст сделать — IQueryable не приводится к IQueryable.

Думаю, что ваш код работает, потому что подготовленный IQueryable уходит в ODataProvider,
который дополнительно преобразовывает выражение.
Я хотел сказать
return ((IQueryable<TEntity>)DbSet<TEntity>()).FirstOrDefault(x => x.Id == "id");


:) DbSet точно должен приводиться к IQueryable.
У нас обоих парсер порезал типизированные генерики )))
В любом случае, явное приведение DbSet к IQueryable ничего не меняет, т.к. FirstOrDefault — это именно метод-расширение интерфейса IQueryable, а не DbSet.
Надо приводить не к IQueryable<TEntity> — это ничего не дает, а к IQueryable<EntityBase>, пользуясь ковариантностью IQueryable<>. В таком случае в лямбде у параметра x будет тип EntityBase — и у компилятора не будет причин явно добавлять преобразование типов.
Я понял.
Гипотеза интересная, но…
var res = (IQueryable<IEntityObjectId>)Db.Set<TEntity>().First(x => x.Id == entity.Id);

выдаёт ту же ошибку (
Вы забыли еще одну пару скобок.

var res = ((IQueryable<IEntityObjectId>)Db.Set<TEntity>()).First(x => x.Id == entity.Id);
Точно! Как я мог так протупить? )))
ТАК ДЕЙСТВИТЕЛЬНО РАБОТАЕТ!
Что-же получается, можно обойтись и без упрощалки экспрешенов.
Спасибо! [])
Меня очень смущает “LINQ to Entities” в тексте ошибки. У меня такое бывало, когда в блоке using был зарефан только System.Ling. Тогда по факту DbSet неявно приводится к IEnumerable и FirstOrDefault применяется уже к нему, используя механизм Linq to Entities вместо Linq to SQL.
У меня:
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;

и да, я проверял — вызывается метод-расширение именно IQueryable интерфейса. Ну и потом, я же EF и использую, а не Linq2Sql
Вы путаете “LINQ to Entities” с “LINQ to Objects”.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации