繁体   English   中英

如何在 Linq 中使用 Dapper

[英]How to use Dapper with Linq

我正在尝试从实体框架转换为 Dapper,以期提高数据访问性能。

我使用的查询采用谓词形式,例如Expression<Func<TModel, bool>>

举个例子:

我有以下代码需要转换为使用 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 试图做的事情。 到目前为止,我会说这是对立的。 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; }
        }
    }
}

我也试过Dapper.Extensions.Linq (你建议的包),它承诺

以此为基础,通过 Linq 查询提供高级数据库访问。 流体配置使设置简单快捷。

不幸的是,我也不能走得很远。 没有太多文档,并且测试似乎没有涵盖 QueryBuilder,这似乎是用于将 Linq 表达式转换为 Dapper Extensions 谓词的类(如问题Parsing boolean expressions with the 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+Products 的运算符

我不确定为什么手动生成 Predicate(第一个示例)有效,但 QueryBuilder 没有。

我想说的是,在您的问题上留下的评论越来越看起来是正确的,您将需要重新编写代码,远离与实体框架一起使用的表达式。 由于很难找到关于这个 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 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM