Dapper를 Linq와 함께 사용하는 법

c# dapper expression linq predicate

문제

나는 데이터 액세스 성능을 향상시키기 위해 Entity Framework에서 Dapper로 변환하려고합니다.

내가 사용하는 쿼리는 "표현식>"과 같은 술어 형식으로되어 있습니다.

예를 들면 다음과 같습니다.

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는 나를 실패하고있다, 누군가 원조 할 수있다.

편집하다:

내가 찾은 점에 유의하십시오 : https://github.com/ryanwatson/Dapper.Extensions.Linq

하지만 그것을 사용하는 방법을 알아낼 수 없습니다.

수락 된 답변

첫째, Dapper의 저자 중 한 사람이 누군가가 물었을 때

Dapper.net을 IQueryable 인터페이스와 호환 가능하게 만들 계획이 있습니까?

이것을 할 계획이 없습니다. 그것은 대퍼가하려고하는 것보다 훨씬 멀리 떨어져 있습니다. 지금까지 나는 그것이 대칭이라고 말할 것입니다. Dapper 코어는 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; }
        }
    }
}

나는 Dapper.Extensions.Linq (당신이 제안한 패키지)를 시도했다.

Linq 쿼리를 통해 고급 DB 액세스를 제공합니다. 유체 구성은 설치를 단순하고 신속하게 만듭니다.

불행히도, 나는 또한 그걸로 아주 멀리 갈 수 없었다. 많은 문서가 없으며 테스트에서 QueryBuilder를 다루지 않는 것 같습니다. 이는 Linq 표현식을 Dapper Extensions 선언문으로 변환하는 데 사용되는 클래스 인 것 같습니다 (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.Program + 제품에 대한 연산자를 찾을 수 없습니다.

왜 수동으로 술어를 생성하는지 (첫 번째 예)는 잘 모르지만 QueryBuilder는 그렇지 않습니다.

귀하의 질문에 남겨진 주석이 정확하고 Entity Framework에서 사용한 표현식에서 코드를 다시 작성해야 할 필요성이 점차 커지고 있습니다. 이 QueryBuilder 클래스에 대한 정보를 찾기가 너무 어려웠 기 때문에 (비록 당신이 작동 시키더라도) 당신이 겪은 모든 문제는 도움을 받기가 어려울 것이고 버그는 수정되지 않을 수도 있습니다.


인기 답변

나는 Dapper와 함께 EF를 사용하여 속성을 사용하는 유틸리티를 작성했습니다. 나는 술어를 파싱하고 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.Dapper.Repositories



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow