【问题标题】:Dapper is returning null when join is introduced to stored procedure将联接引入存储过程时,Dapper 返回 null
【发布时间】:2022-01-19 18:19:57
【问题描述】:

我有一个特殊的问题,我似乎找不到任何答案。似乎当我向存储过程引入连接时,Dapper 的映射拒绝正常工作。

我的自定义对象:

public class CustomObject
{
    public string ColumnOne { get; set; }
    public string ColumnTwo { get; set; }
    public DateTime? ColumnThree { get; set; }
    public string ColumnFour { get; set; }
}

在我的存储库调用中,customObjects 始终返回 0 个结果。

我使用 Dapper 调用存储库:

public IEnumerable<CustomObject> GetTheThings(int? integerParameter)
{
    List<CustomObject> customObjects;

    using (var connection = "connection string syntax"))
    {
        string sql = "[storedProcedureName]";

        connection.Open();

        customObjects = connection.Query<CustomObject>(sql,
                new { IntegerParameter = integerParameter },
                commandType: CommandType.StoredProcedure).ToList();
    }

    return customObjects;
}

存储过程的基本语法:

SELECT  
    t1.column_one AS [ColumnOne],         -- column_one is nvarchar data type
    t2.column_two_thing AS [ColumnTwo],   -- column_two_thing is nvarchar data type
    t2.column_three AS [ColumnThree],     -- column_three is DateTime data type
    t2.column_four AS [ColumnFour]        -- column_four is nvarchar data type
FROM 
    Table1 t1 WITH (NOLOCK)
JOIN 
    Table2 t2 WITH (NOLOCK) ON t1.Identifier = t2.Identifier -- Identifiers are both uniqueidentifier data types
WHERE 
    t1.column_one = @IntegerParameter;

当我直接在 SSMS 中执行此存储过程时,它会返回我期望的值和我期望的格式

ColumnOne ColumnTwo ColumnThree ColumnFour
TextOne ColumnTwoResultTextOne 2021-12-16 00:00:00.001 ColumnFourResultTextOne
TextOne ColumnTwoResultTextTwo 2021-12-16 00:00:00.001 ColumnFourResultTextTwo
TextOne ColumnTwoResultTextThree 2021-12-16 00:00:00.001 ColumnFourResultTextThree
TextOne ColumnTwoResultTextFour 2021-12-16 00:00:00.001 ColumnFourResultTextFour

当我在运行时使用 Dapper 通过我的应用程序执行时,返回的结果为 0。

由于某种原因,当我删除连接并手动为依赖连接的列键入值时,我会收到返回的结果。

适当返回结果和映射的脚本:

SELECT  
    t1.column_one AS [ColumnOne],         -- column_one is nvarchar data type
    'Literally anything' AS [ColumnTwo],  -- column_two_thing is nvarchar data type
    GETDATE() AS [ColumnThree],           -- column_three is DateTime data type
    'Anything here too' AS [ColumnFour]   -- column_four is nvarchar data type
FROM 
    Table1 t1 WITH (NOLOCK)
WHERE 
    t1.column_one = @IntegerParameter;

我还尝试用硬编码的'Literally anything' as [ColumnName] 替换每一列,以确保它不仅仅是在 Dapper 翻译中丢失的属性,而且只要连接在我的方法中,就不会在运行时返回任何结果查询。

我一直在阅读 Dapper 文档并仔细阅读 StackOverflow 和其他资源以获取任何建议,但找不到我出错的地方。

我们将不胜感激任何和所有的帮助或建议!

【问题讨论】:

  • @Larnu,谢谢你发帖。这些记录发生脏读的可能性非常低,因此释放线程具有更高的重要性。
  • 如果没有其他人访问该表的机会,为什么不使用TABLOCKSNAPSHOT?如果由于其他客户端访问该表而您不能这样做,那么您就有脏读。为什么您认为“释放线程”是您遇到的问题?
  • 请提供包含 actual 表定义和 actual 查询的minimal reproducible example。我非常怀疑 Dapper 是否与此有关,几乎可以肯定是连接问题
  • 现在释放什么? NOLOCK 对线程完全没有任何作用。值得注意的是,如果行没有被修改,则不使用读锁不会以某种方式提高并发吞吐量,而如果它们被修改显然是个坏主意。您应该考虑NOLOCK 的唯一时间是您是否可以不关心不正确的结果(例如,因为无论如何都会定期执行查询),而不是因为您对赔率感觉良好。如果您希望确保读取器和写入器不会相互阻塞,请考虑快照隔离。

标签: c# sql-server tsql dapper


【解决方案1】:

您根本没有得到任何行的事实表明您的两个表中没有可以连接的结果。

JOIN 语句默认为内连接。这将仅返回在两个表中具有匹配值的记录。

编辑:在这种情况下,在 SSMS 和 Dapper 中运行查询之间的不一致是因为连接字符串中帐户的权限不同。因此无法访问其中一个表中的数据,因此 JOIN 没有返回任何行。

【讨论】:

  • 执行 LEFT JOIN 时,我收到一个返回的结果,其中 ColumnOne 和 ColumnThree 在运行时填充,但其他两个仍然为空。当我在数据库中运行 LEFT JOIN 时,它仍然返回多个结果,每列填充。
  • 存在差异的事实似乎证实了数据库中没有可以加入的数据。我意识到这可能是一个愚蠢的建议 - 但您确定代码与您的 SSMS 连接与同一个数据库通信吗?
  • 是的,我只是三重检查以确保它是相同的服务器、相同的数据库和连接字符串都已设置。这是我今天早上编写的一个新的存储过程,我正在本地运行它以验证它是否击中了正确的位置。
  • 好吧,我已经想通了,我认为您的 cmets 帮助我朝着正确的方向前进。我遇到的问题是连接字符串中标识的帐户无权查看其中一个联接表中的数据。实际上,我最终淘汰了 Dapper 并手动执行和映射我的对象,这样我就可以调试更多。看到只有一个表返回了任何数据,我挖掘了连接字符串,以用户身份登录,然后在存储过程中执行查询。
  • 好吧,我不能声称我回答了你的问题:D 我会为未来的用户更新这个问题。有时只需要向其他人解释即可。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-07-29
  • 1970-01-01
  • 2014-08-04
  • 1970-01-01
  • 1970-01-01
  • 2020-05-01
  • 2021-06-11
相关资源
最近更新 更多