Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何与Linq一起使用Dapper_C#_Linq_Expression_Dapper_Predicate - Fatal编程技术网

C# 如何与Linq一起使用Dapper

C# 如何与Linq一起使用Dapper,c#,linq,expression,dapper,predicate,C#,Linq,Expression,Dapper,Predicate,我正在尝试从实体框架转换为Dapper,希望能够提高数据访问性能 我使用的查询是谓词的形式,比如soExpression 举个例子: 我有以下代码,我需要使用Dapper将其转换为 我目前的工作: public async Task<List<TModel>> Get(Expression<Func<TModel, bool>> query) { // this.Context is of type DbContext return

我正在尝试从实体框架转换为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();
}
公共异步任务获取(表达式查询)
{
//此.Context的类型为DbContext
return wait this.Context.Set().Where(query.toListSync();
}
我想做的是:

public async Task<List<TModel>> Get(Expression<Func<TModel, bool>> query)
{
    using (IDbConnection cn = this.GetConnection)
    {
        return await cn.QueryAsync<TModel>(query);
    }
}
公共异步任务获取(表达式查询)
{
使用(IDbConnection cn=this.GetConnection)
{
返回等待cn.QueryAsync(查询);
}
}
我的google fu让我失望了,请有人帮忙

编辑:

请注意,我确实发现:


但我似乎不知道如何使用它。

首先,当有人问起时,Dapper的一位作者说

是否有计划使Dapper.net与IQueryable接口兼容

没有这样做的计划。这远远超出了dapper试图做的事情。到目前为止,我认为这是相反的。Dapper core努力成为热爱SQL的人的朋友

(见附件)

在某种程度上,这确实表明NuGet的各种扩展包可能会有所帮助,正如您所建议的那样

我已经尝试过了,这使得以编程的方式编写查询过滤器变得更容易了

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; }
        }
    }
}
使用System.Data.SqlClient;
使用DapperExtension;
命名空间StackOverflowAnswer
{
班级计划
{
静态void Main(字符串[]参数)
{
使用(var cn=new-SqlConnection(“服务器=;数据库=NORTHWND;可信连接=True;”)
{
var list=cn.GetList(
谓词.Field(f=>f.contracted,Operator.Eq,false)
);
}
}
类产品
{
public int ProductId{get;set;}
公共字符串ProductName{get;set;}
公共布尔已中断{get;set;}
}
}
}
我也试过(你建议的方案),它承诺

在此基础上,通过Linq查询提供高级数据库访问。流体配置使设置变得简单和快速

不幸的是,我也没能走得很远。没有太多文档,测试似乎也没有涵盖QueryBuilder,QueryBuilder似乎就是用来将Linq表达式转换为Dapper扩展谓词的类(正如问题所建议的)。我尝试了以下操作,这需要将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; }
        }
    }
}
使用系统;
使用System.Data.SqlClient;
使用System.Linq.Expressions;
使用Dapper.Extensions.Linq.Builder;
使用Dapper.Extensions.Linq.Core;
使用DapperExtension;
命名空间StackOverflowAnswer
{
班级计划
{
静态void Main(字符串[]参数)
{
使用(var cn=new-SqlConnection(“服务器=;数据库=NORTHWND;可信连接=True;”)
{
表达式filter=p=>!p.contracted;
var queryFilter=QueryBuilder.FromExpression(过滤器);
var list=cn.GetList(
查询过滤器
);
}
}
类别产品:绿色
{
public int ProductId{get;set;}
公共字符串ProductName{get;set;}
公共布尔已中断{get;set;}
}
}
}
。。但它在运行时失败,出现了错误

找不到StackOverflowAnswer的运算符。程序+产品

我不确定为什么手动生成谓词(第一个示例)可以工作,但QueryBuilder不能


我想说的是,在您的问题上留下的评论越来越像是正确的,您将需要重新编写代码,使其远离您在Entity Framework中使用的表达式。因为很难找到关于这个QueryBuilder类的任何信息,所以我担心(即使您确实让它工作了)您遇到的任何问题都很难得到帮助(bug可能会被修复)。

我编写了一个实用程序,使用属性与Dapper一起工作。我分析谓词并将其转换为SQL

“用户”POCO:

简单查询:

using (var cn = new SqlConnection("..."))
{
    var usersRepository = new DapperRepository<User>(cn)
    var allUsers = await userRepository.FindAllAsync(x => x.AccountId == 3 && x.Status != UserStatus.Deleted);
}
使用(var cn=new-SqlConnection(“…”)
{
var usersRepository=新的DapperRepository(cn)
var allUsers=await userRepository.findalsync(x=>x.AccountId==3&&x.Status!=UserStatus.Deleted);
}
也许对你有用


LINQ to EF从实体模型和LINQ谓词构造SQL语句。Dapper执行实际的SQL语句,并“简单地”映射结果。您必须编写完整的SQL参数化SQL语句。换句话说,您确定没有解决错误的问题吗?您可以简单地向任何查询添加另一个Where子句,例如
var query=context.SomeEntity.Where()。。。。;query=query.Where(…);query=query.Select(…)。如果只想向现有查询添加筛选器,则不需要使用表达式。移动到微型ORM并不会使查询的运行时构造更容易。对于Dapper,cn.QueryAsync(查询),查询应该是sql字符串而不是表达式。您必须在从EF转换时进行重大更改。谢谢你花时间研究我的问题。我很高兴(也很难过)有人得出了与我相同的结论。非常感谢。我想补充一下。即使那些小心翼翼的作者可能会把某些东西作为LINQ的扩展来考虑它的预期目的,但我相信这样的事情有很好的理由和好处。首先,这些库提供了针对sql注入攻击的内置保护。其次,你得到了智能感知的好处。您可以获得所有这些,同时还可以获得简洁的稳定性和可靠性,而无需
using (var cn = new SqlConnection("..."))
{
    var usersRepository = new DapperRepository<User>(cn)
    var allUsers = await userRepository.FindAllAsync(x => x.AccountId == 3 && x.Status != UserStatus.Deleted);
}