C# 如何在条件StringBuilder查询中使用Dapper?

C# 如何在条件StringBuilder查询中使用Dapper?,c#,dapper,C#,Dapper,我试图构建一个动态查询字符串,并将其应用到dapper上,以某种方式给人一种类似实体框架可选的感觉。includex=>x.XXX功能: 生成查询字符串 进程查询 但由于这些信息类似于一对一的关系,我认为单次查询更好。所以,我试图避免使用这个解决方案 我也不想列出所有可能的泛型签名组合,如: 连接.查询 连接.查询 连接.查询 连接.查询 当我开始向这个类添加更多的1对1关系时,这种方法就是不友好的 我怎样才能解决这个问题 您需要告诉dapper在何处拆分—对象之间的边界在select语句中的何

我试图构建一个动态查询字符串,并将其应用到dapper上,以某种方式给人一种类似实体框架可选的感觉。includex=>x.XXX功能:

生成查询字符串

进程查询

但由于这些信息类似于一对一的关系,我认为单次查询更好。所以,我试图避免使用这个解决方案

我也不想列出所有可能的泛型签名组合,如:

连接.查询 连接.查询 连接.查询 连接.查询 当我开始向这个类添加更多的1对1关系时,这种方法就是不友好的


我怎样才能解决这个问题

您需要告诉dapper在何处拆分—对象之间的边界在select语句中的何处。这就是错误语句所说的。因此,请将您的呼叫修改为:

pst = multi.Read<Post, User, PostStatus, Post>((post, user, status) =>
{
   if (post == null) return null;
   if (user != null) post.Creator = user;
   if (status != null) post.Status = status;
   return post;
}, splitOn: "Id,Id").FirstOrDefault();
在“告诉Dapper在哪里停止映射到一个对象并开始映射到另一个对象”上进行拆分。由于有2个联接,因此需要在“拆分”中有两个字段。确保这两个字符放在一个由逗号分隔的字符串中,并且字符串中没有空格字符

如需更好的解释,请参阅本帖:


我找到了一种不那么糟糕的方法:

        var query = new StringBuilder();
        query.Append(" select * from test_post p ");

        query.Append(validIncludesToPerform[0]
            ? " left join sys_user u on u.Id = p.CreatorId "
            : " left join sys_user u on 1 = 0 ");

        query.Append(validIncludesToPerform[1]
            ? " left join test_poststatus s on s.Id = p.StatusId "
            : " left join test_poststatus s on 1 = 0 ");

        query.Append(" where p.Id = @Id; ");

我将暂时保留此答案,等待更好的选择……

我感谢您的帮助,不幸的是,您的解决方案不起作用,也不会更改我的代码中的任何内容,因为您的id为的拆分与我不编写代码时的代码完全相同,因为Dapper上的官方描述是:Dapper假设您的Id列命名为Id或Id,如果主键不同,或者您希望在Id以外的点拆分宽行,请使用可选的“splitOn”参数。我不确定您是否阅读了我的描述,但当至少有一个ValidIncludestOperature[0]时validIncludesToPerform[1]为FALSE,则我收到的错误消息与问题文本中描述的消息相同。当我试图用Creator和Status加载所有帖子时,我没有任何错误,这正好说明我的观点是使用拆分器,这在我的情况下是多余的。@Dryadwoods我读了你的帖子,我读了你的错误消息,其中清楚地说明了split on存在问题。无论如何,我的猜测是,您有任意数量的join语句,但您有一组数量的对象被映射到3个,因此拆分时需要2个参数,但连接的数量根据您的条件而变化。所以,当连接数不完全是2时,你就有问题了……完全正确,我的问题中也已经说明了这个原因。我知道我可以通过有多个条件和不同的通用签名来克服这个问题:Query或.Query或Query或Query。。。但是,当我有更多的1对1关系时,这就不能很好地伸缩。为什么有条件连接?为什么不只有连接?或者如果不确定是否有关联的对象,为什么不有外部连接?您真的那么关心性能吗?您可以发布最终的sql查询,可能带有类和sql表定义。@Yildzm85,我的问题中缺少省略的信息,通过提供完整的类/sql表可以改进它?如果这真的能让你对如何给我一个答案有更多的了解。我可以再问一次,我会做的。至少构建查询字符串的部分不是关于这个问题。我只是说你的问题应该是最小的。见:
if (validIncludesToPerform[0])
   query.Append(@" select u.* from sys_user u right join test_post p on u.Id = p.CreatorId 
                   where p.Id = @Id;");
if (validIncludesToPerform[1])
   query.Append(@" select ps.* from test_poststatus ps right join test_post p on ps.Id = p.StatusId 
                   where p.Id = @Id;");
pst = multi.Read<Post, User, PostStatus, Post>((post, user, status) =>
{
   if (post == null) return null;
   if (user != null) post.Creator = user;
   if (status != null) post.Status = status;
   return post;
}, splitOn: "Id,Id").FirstOrDefault();
        var query = new StringBuilder();
        query.Append(" select * from test_post p ");

        query.Append(validIncludesToPerform[0]
            ? " left join sys_user u on u.Id = p.CreatorId "
            : " left join sys_user u on 1 = 0 ");

        query.Append(validIncludesToPerform[1]
            ? " left join test_poststatus s on s.Id = p.StatusId "
            : " left join test_poststatus s on 1 = 0 ");

        query.Append(" where p.Id = @Id; ");