如何将 Dapper 与 Linq 一起使用
How to use Dapper with Linq
我正在尝试从 Entity Framework 转换为 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的一位作者说,当有人问
Is there a plan to make Dapper.net compatible with IQueryable interfaces?
那个
there are no plans to do this. It is far far outside what dapper tries to do. So far that I would say it is antithetical. Dapper core tries to be the friend to those who love their SQL.
(参见 )。
在某种程度上,这确实表明 NuGet 的各种扩展包可能会有所帮助,正如您所建议的那样。
我试过 DapperExtensions,这使得以编程方式编写查询过滤器更容易一些 - 例如。
using System.Data.SqlClient;
using DapperExtensions;
namespace WhosebugAnswer
{
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(你建议的包),它承诺
builds on this providing advanced DB access through Linq queries. The fluid configuration makes setup simplistic and quick.
不幸的是,我也无法深入了解它。没有太多文档,测试似乎没有涵盖 QueryBuilder,这似乎是 class 用于将 Linq 表达式转换为 Dapper 扩展谓词的东西(如问题 [=19 所建议的那样) =]).我尝试了以下操作,这需要将 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 WhosebugAnswer
{
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; }
}
}
}
.. 但它在运行时失败并出现错误
Operator was not found for WhosebugAnswer.Program+Products
我不确定为什么手动生成谓词(第一个示例)有效但 QueryBuilder 不...
我想说的是,您的问题上留下的评论看起来越来越正确,您将需要重新编写代码,远离您在 Entity Framework 中使用的表达式。由于很难找到有关此 QueryBuilder class 的任何信息,我担心(即使你确实让它工作)你遇到的任何问题都很难获得帮助(并且错误可能未修复) ).
我编写了一个实用程序来使用属性将 EF 与 Dapper 一起使用。我解析谓词并翻译成 SQL.
"Users" 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);
}
也许它对你有用?
我正在尝试从 Entity Framework 转换为 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的一位作者说,当有人问
Is there a plan to make Dapper.net compatible with IQueryable interfaces?
那个
there are no plans to do this. It is far far outside what dapper tries to do. So far that I would say it is antithetical. Dapper core tries to be the friend to those who love their SQL.
(参见 )。
在某种程度上,这确实表明 NuGet 的各种扩展包可能会有所帮助,正如您所建议的那样。
我试过 DapperExtensions,这使得以编程方式编写查询过滤器更容易一些 - 例如。
using System.Data.SqlClient;
using DapperExtensions;
namespace WhosebugAnswer
{
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(你建议的包),它承诺
builds on this providing advanced DB access through Linq queries. The fluid configuration makes setup simplistic and quick.
不幸的是,我也无法深入了解它。没有太多文档,测试似乎没有涵盖 QueryBuilder,这似乎是 class 用于将 Linq 表达式转换为 Dapper 扩展谓词的东西(如问题 [=19 所建议的那样) =]).我尝试了以下操作,这需要将 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 WhosebugAnswer
{
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; }
}
}
}
.. 但它在运行时失败并出现错误
Operator was not found for WhosebugAnswer.Program+Products
我不确定为什么手动生成谓词(第一个示例)有效但 QueryBuilder 不...
我想说的是,您的问题上留下的评论看起来越来越正确,您将需要重新编写代码,远离您在 Entity Framework 中使用的表达式。由于很难找到有关此 QueryBuilder class 的任何信息,我担心(即使你确实让它工作)你遇到的任何问题都很难获得帮助(并且错误可能未修复) ).
我编写了一个实用程序来使用属性将 EF 与 Dapper 一起使用。我解析谓词并翻译成 SQL.
"Users" 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);
}
也许它对你有用?