提问者:小点点

使用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,以及参数名以@开头和不以@开头。 存储过程中的两列都属于DateTime类型。

我做错了什么?


共2个答案

匿名用户

您只需给参数取一个正确的名称:

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

匿名用户

您可以使用queryQueryAsync或任何其他查询方法,如QueryFirstQueryFirstorDefaultexecutescalar是ADO.NET方法,也存在于dapper中,因此可能不清楚您使用的是哪个方法。

衣冠楚楚的尝试

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

为什么使用query()而不是execute()? 您需要一个返回值。

此外,还应该在查询和匿名类型中指定参数的名称。