Как использовать Dapper с Linq

Я пытаюсь преобразовать из Entity Framework в Dapper, чтобы, надеюсь, повысить производительность доступа к данным.

запросы, которые я использую, имеют форму предикатов типа so " Expression>".

приведу пример:

у меня есть следующий код, который мне нужно преобразовать в использование Dapper.

что я сейчас делаю:

public async Task<List<TModel>> Get(Expression<Func<TModel, bool>> query)
{
    // this.Context is of type DbContext
    return await this.Context.Set<TModel>().Where(query).ToListAsync();
}

что я хотел бы сделать:

public async Task<List<TModel>> Get(Expression<Func<TModel, bool>> query)
{
    using (IDbConnection cn = this.GetConnection)
    {
        return await cn.QueryAsync<TModel>(query);
    }
}

мой google-fu подводит меня, может кто-то, пожалуйста помогать.

Edit:

обратите внимание, что я нашел: https://github.com/ryanwatson/Dapper.Extensions.Linq

но я не могу понять, как его использовать.

2 ответов


во-первых, один из авторов Dapper сказал, когда кто-то спросил

есть ли план, чтобы сделать Dapper.net совместимость с интерфейсами IQueryable?

это

нет никаких планов, чтобы сделать это. Это далеко за пределами того, что пытается сделать щеголь. Пока что я бы сказал, что это противоречит. Dapper core пытается быть другом для тех, кто любит свой SQL.

(см. https://stackoverflow.com/a/27588877/3813189).

таким образом, это предполагает, что различные пакеты расширений для NuGet могут помочь, как вы предложили.

Я пробовал DapperExtensions, что делает написание фильтров запросов программным способом немного проще-например.

using System.Data.SqlClient;
using DapperExtensions;

namespace StackOverflowAnswer
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var cn = new SqlConnection("Server=.;Database=NORTHWND;Trusted_Connection=True;"))
            {
                var list = cn.GetList<Products>(
                    Predicates.Field<Products>(f => f.Discontinued, Operator.Eq, false)
                );
            }
        }

        class Products
        {
            public int ProductId { get; set; }
            public string ProductName { get; set; }
            public bool Discontinued { get; set; }
        }
    }
}

Я тоже пробовал щеголь.Увеличение.В LINQ (пакет, который вы предложили), который обещает

строит на этом предоставление расширенного доступа к БД через Linq-запросы. Жидкая конфигурация делает установку упрощенным и быстрым.

к сожалению, я также не мог получить очень далеко. Существует не так много документации, и тесты, похоже, не охватывают QueryBuilder, который, по-видимому, является классом для перевода выражений Linq в предикаты расширений Dapper (как предложено проблемой разбор логических выражений с помощью QueryBuilder). Я попытался следующее, что требуется добавить интерфейс IEntity в мой DTO -

using System;
using System.Data.SqlClient;
using System.Linq.Expressions;
using Dapper.Extensions.Linq.Builder;
using Dapper.Extensions.Linq.Core;
using DapperExtensions;

namespace StackOverflowAnswer
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var cn = new SqlConnection("Server=.;Database=NORTHWND;Trusted_Connection=True;"))
            {
                Expression<Func<Products, bool>> filter = p => !p.Discontinued;
                var queryFilter = QueryBuilder<Products>.FromExpression(filter);

                var list = cn.GetList<Products>(
                    queryFilter
                );
            }
        }

        class Products : IEntity
        {
            public int ProductId { get; set; }
            public string ProductName { get; set; }
            public bool Discontinued { get; set; }
        }
    }
}

.. но это не удалось во время выполнения с ошибкой

оператор не найден для StackOverflowAnswer.Программа + Продукты

Я не уверен, почему создание предиката вручную (первый пример) работает, но QueryBuilder этого не делает..

Я бы сказал, что все больше похоже, что комментарии, оставленные на ваш вопрос, верны, что вам нужно будет повторно обработайте код от выражений, которые вы использовали с Entity Framework. Поскольку было так сложно найти какую-либо информацию об этом классе QueryBuilder, я был бы обеспокоен тем, что (даже если вы его заработали) любые проблемы, с которыми вы столкнулись, будет трудно получить помощь (и ошибки могут быть незафиксированными).


Я написал утилиту для работы EF с Dapper, используя атрибуты. Я разбираю предикат и переводю на SQL.

"пользователи" POCO:

[Table("Users")]
public class User
{
    [Key]
    [Identity]
    public int Id { get; set; }

    public string Login { get; set;}

    [Column("FName")]
    public string FirstName { get; set; }

    [Column("LName")]
    public string LastName { get; set; }

    public string Email { get; set; }

    [NotMapped]
    public string FullName
    {
        get
        {
            return string.Format("{0} {1}", FirstName, LastName);
        }
    }
}

и простой запрос:

using (var cn = new SqlConnection("..."))
{
    var usersRepository = new DapperRepository<User>(cn)
    var allUsers = await userRepository.FindAllAsync(x => x.AccountId == 3 && x.Status != UserStatus.Deleted);
}

может быть, это будет полезным для вас?

MicroOrm.Щеголеватый.Хранилища