2015-03-30 2 views
3

Если у меня есть метод, который возвращает List of Dogs, делает Dapper конвертировать предикат Where в SQL Где? или он сначала получает всех собак, а затем фильтрует список?Что будет делать с предикатом?

public IList<Dog> GetDogsBy(Func<Dog, bool> predicate) 
{ 
    return db.Query<Dog>("SELECT * FROM Dog",null).Where(predicate).ToList(); 
} 
+2

Этот, безусловно, будет выполнен вашим приложением, а не переведен на SQL. – MarcinJuraszek

+3

Подтвердить; этот предикат является LINQ-to-Objects и не обрабатывается dapper. Dapper не претендует на полноту ORM. Там * * некоторые полезные общие предикаты и т. Д. Инструменты в некоторых дополнительных связанных инструментах dapper, однако –

+0

Как насчет того, как вы рассматриваете использование Dapper-Extensions (https://github.com/tmsmith/Dapper-Extensions)? –

ответ

3

Когда дело доходит до SQL trnalsation, в то время как выражения дерево может быть переведено, составлен методом не может. Это связано с тем, что как только метод скомпилирован, это вопрос чтения IL для выполнения перевода, который не отображается через .NET API, тогда как деревья выражений явно предназначены для навигации с использованием метакода для перевода.

Поскольку вы передаете Func<...> вместо Expression<Func<...>>, вы передаете этот скомпилированный метод, и, следовательно, код не может получить дерево выражений, и, следовательно, приведенный выше код не будет работать или будет выполняться на вашем локальном машина.

Если вы должны были заменить метод подписи с

public IList<Dog> GetDogsBy(Expression<Func<Dog, bool>> predicate) 

Тогда это могло бы быть в состоянии выполнить преобразование, в зависимости от семантики Dapper.

17

Это зависит от разрешения перегрузки при разрешении Where.

Если результат вызова Query является List<Dog> и у вас есть using System.Linq; директиву, а аргумент является делегатом, то Where рассосется версии LINQ-к-объектов Where. Таким образом, запрос выбора будет выполняться на сервере, а затем на клиенте будет запущен Where.

Если результат Query является IQueryable<Dog> и аргумент является разрешение Expression то перегружать будет выбрать Where, который сочетает в себе с существующим запросом. Когда этот запрос выполняется, Where работает на той стороне, на которую провайдеры запросов решают запустить его, что обычно является сервером.

+3

Я смущен, увидев, что у вас есть нисходящее движение для абсолютно правильного ответа, который охватывал обе возможности. Как это бывает, dapper просто возвращает 'IEnumerable ' и не пытается обработать деревья выражений, поэтому ваше первое объяснение применяется. Независимо от того, является ли этот 'IEnumerable ' 'списком ' против неполной открытой последовательности, сидящей над читателем ADO.NET, зависит от необязательного параметра 'buffered'. –

+1

@MarcGravell: Спасибо за дополнительные подробности! –

Смежные вопросы