如何使用 Dapper 将日期时间传递给存储过程?

How to pass a DateTime into a Stored Procedure using Dapper?

我有这个存储过程:

CREATE PROCEDURE [dbo].[IsDateInBetween]
    @someDateTime datetime
AS
BEGIN
    DECLARE @Exists INT

    IF EXISTS(SELECT Id FROM [dbo].[SomeTable] 
               WHERE StartDate < @someDateTime AND EndDate > @someDateTime)
    BEGIN
        SET @Exists = 1
    END
    ELSE
    BEGIN
        SET @Exists = 0
    END

    RETURN @Exists
END

当我调用它时:

DECLARE @return_value int

EXEC    @return_value = [dbo].[IsDateInBetween]
        @someDateTime = N'2020-07-14'

SELECT  'Return Value' = @return_value

GO

我收到 1,这是预期的。

但后来我尝试在 C# 中调用它:

var result = DbConnection.ExecuteScalar<int>("dbo.IsDateInBetween", new { new DateTime(2020, 7, 14) }, commandType: CommandType.StoredProcedure);

我得到 0。

我试图将传递的对象更改为 DynamicParameters,就像那样:

var parameters = new DynamicParameters();
parameters.Add("someDateTime", faultDateTime, DbType.DateTime);

但是没有用。

我尝试了 DbType.DateTime 和 DbType.DateTime2,以及以 @ 开头和不以 @ 开头的参数名称。 存储过程中的两列都是日期时间类型。

我做错了什么?

您可以使用 QueryQueryAsync 或任何其他查询方法,例如 QueryFirstQueryFirstOrDefaultExecuteScalar 是一种 ADO.net 方法,也存在于 dapper 中,因此可能不清楚 您正在使用的方法。

想要小巧的试试

DbConnection.QueryFirst<int>("EXEC dbo.IsDateInBetween @someDate", new { someDate = new DateTime(2020, 7, 14) });

为什么使用 Query() 而不是 Execute()?您期望 return 值。

您还应该在查询中以匿名类型指定参数的名称。

您只需为您的参数指定正确的名称:

var result = DbConnection.ExecuteScalar<int>(
    "IsDateInBetween", 
    new { someDateTime = new DateTime(2020, 7, 14) }, 
    commandType: CommandType.StoredProcedure);

此外,除非您执行的模式与登录的默认模式不同,否则您无需提及,过程名称就足够了。

还有一件事 - 问题可能出在存储过程本身。您不应该使用 Return - 您应该使用输出参数或简单的 select.

试试这个程序:

CREATE OR ALTER PROCEDURE [dbo].[IsDateInBetween]
    @someDateTime datetime
AS
BEGIN
    SELECT CASE WHEN EXISTS(
        SELECT Id 
        FROM [dbo].[SomeTable] 
        WHERE StartDate < @someDateTime 
        AND EndDate > @someDateTime
    )
    THEN 1
    ELSE 0
    END
END