You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EF Core .NET7迁移中调用带DateTime参数存储过程无结果问题

EF Core调用存储过程DateTime参数无结果问题排查与修复

问题现象

将EF6项目迁移至.NET7 EF Core后,数据库表创建正常,但调用存储过程tsp_GetDocuments时出现异常:

  • 在SSMS中执行存储过程传入@fromDate能得到预期结果
  • 应用中传入fromDate参数无返回结果,不传该参数则有部分结果

代码错误分析

参数赋值错误

在创建@fromDate参数时,错误地将Value赋值为toDate,导致实际传入存储过程的@fromDate是toDate的值,而非方法参数的fromDate:

// 错误代码
new SqlParameter() {
    ParameterName = "@fromDate",
    SqlDbType = System.Data.SqlDbType.DateTime,
    Direction = ParameterDirection.Input,
    Value = (object)toDate ?? DBNull.Value // 此处应为fromDate
}

FromSqlInterpolated用法错误

使用FromSqlInterpolated时,错误地将SqlParameter对象直接插入到SQL字符串中,还额外给第一个参数加了单引号,这会导致参数传递格式错误,SQL无法正确解析DateTime值:

// 错误代码
FromSqlInterpolated<tsp_GetDocuments_Result>($"EXECUTE [dbo].[tsp_GetDocuments] '{@params[0]}',{@params[1]},{@params[2]},{@params[3]},{@params[4]}")

修正后的代码

public partial class Entities : DbContext
{
    public virtual DbSet<tsp_GetDocuments_Result> tsp_GetDocuments_Result { get; set; }

    partial void OnModelCreatingPartial(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<tsp_GetDocuments_Result>(entity =>
            entity.HasKey(e => e.IdDocumentHeader));
    }

    public IEnumerable<tsp_GetDocuments_Result> tsp_GetDocuments(DateTime? fromDate, DateTime? toDate, int? warehouseFrom, int? warehouseTo, string documentType)
    {
        // 修正参数赋值错误
        var fromDateParam = new SqlParameter("@fromDate", SqlDbType.DateTime) 
        { 
            Value = fromDate.HasValue ? (object)fromDate : DBNull.Value 
        };
        var toDateParam = new SqlParameter("@toDate", SqlDbType.DateTime) 
        { 
            Value = toDate.HasValue ? (object)toDate : DBNull.Value 
        };
        var warehouseFromParam = new SqlParameter("@warehouseFrom", SqlDbType.Int) 
        { 
            Value = warehouseFrom.HasValue ? (object)warehouseFrom : DBNull.Value 
        };
        var warehouseToParam = new SqlParameter("@warehouseTo", SqlDbType.Int) 
        { 
            Value = warehouseTo.HasValue ? (object)warehouseTo : DBNull.Value 
        };
        var documentTypeParam = new SqlParameter("@documentType", SqlDbType.VarChar, 20) 
        { 
            Value = documentType ?? DBNull.Value 
        };

        // 使用FromSqlRaw并传入参数数组,避免插值格式错误
        var results = tsp_GetDocuments_Result
            .FromSqlRaw("EXECUTE [dbo].[tsp_GetDocuments] @fromDate, @toDate, @warehouseFrom, @warehouseTo, @documentType",
                fromDateParam, toDateParam, warehouseFromParam, warehouseToParam, documentTypeParam)
            .ToArray();

        return results;
    }
}

额外优化建议

  • 存储过程的参数如果允许为空,建议在定义时加上NULL默认值,比如@fromDate DATETIME = NULL,这样调用时可以省略不需要的参数
  • 可以使用EF Core的简化写法,直接传递方法参数而非手动创建SqlParameter,EF会自动处理参数转换:
// 简化写法
public IEnumerable<tsp_GetDocuments_Result> tsp_GetDocuments(DateTime? fromDate, DateTime? toDate, int? warehouseFrom, int? warehouseTo, string documentType)
{
    return tsp_GetDocuments_Result
        .FromSqlInterpolated($"EXECUTE [dbo].[tsp_GetDocuments] {fromDate}, {toDate}, {warehouseFrom}, {warehouseTo}, {documentType}")
        .ToArray();
}

内容的提问来源于stack exchange,提问作者Martina

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 08:42:48