将Null Date参数从C#传递到SQL将返回计数列中为零的数据
我试图从C#向SQL存储过程传递一个空日期参数。如果直接运行存储过程,则会在total列中获得值: 但是,如果从C#代码调用存储过程并传递null Date参数,则所有行的Total列将返回零(0): 如果date参数为null,我在存储过程中设置date参数,因此它返回正确的记录,而不是总计 这是我的存储过程代码:将Null Date参数从C#传递到SQL将返回计数列中为零的数据,c#,sql-server,C#,Sql Server,我试图从C#向SQL存储过程传递一个空日期参数。如果直接运行存储过程,则会在total列中获得值: 但是,如果从C#代码调用存储过程并传递null Date参数,则所有行的Total列将返回零(0): 如果date参数为null,我在存储过程中设置date参数,因此它返回正确的记录,而不是总计 这是我的存储过程代码: DECLARE @StartDate date= null, @EndDate date = null If(@StartDate IS NULL) SET @StartDa
DECLARE @StartDate date= null, @EndDate date = null
If(@StartDate IS NULL) SET @StartDate = getDate()-30;
If(@EndDate is NULL) SET @EndDate = getDate();
WITH
L0 AS ( SELECT 1 AS c
FROM (VALUES(1),(1),(1),(1),(1),(1),(1),(1),
(1),(1),(1),(1),(1),(1),(1),(1)) AS D(c) ),
L1 AS ( SELECT 1 AS c FROM L0 AS A CROSS JOIN L0 AS B ),
L2 AS ( SELECT 1 AS c FROM L1 AS A CROSS JOIN L1 AS B ),
Nums AS ( SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS rownum
FROM L2 ),
Date_Range_T (d_range) AS (
SELECT TOP(DATEDIFF(day, @StartDate, @EndDate) + 1)
DATEADD(day, rownum - 1, @StartDate) AS d_range
FROM Nums
)
SELECT CONVERT(VARCHAR, d_range, 101) AS CreateDate, COUNT(R.Id) AS Total
FROM Date_Range_T
LEFT JOIN tbl_Support_Requests R ON Cast(R.CreatedDate as date) = d_range
LEFT JOIN dbo.tbl_Employee_Companies ec on ec.Id = R.ReporterId
GROUP BY d_range
ORDER BY d_range ASC
OPTION (MAXRECURSION 366);
以下是我的C#方法:
public List GetSupportTicketMetrics\u ByDateRange(字符串startDate,字符串endDate)
{
DateTime?StartDate=null;
DateTime?EndDate=null;
如果(开始日期!=“”)
{
StartDate=转换为ToDateTime(StartDate);
}
如果(结束日期!=“”)
{
EndDate=Convert.ToDateTime(EndDate);
}
var list=新列表();
var sql=“exec stp_GetSupportTicketMetrics_ByDateRange{0},{1};”;
尝试
{
使用(var sdb=new SafetyDataContext())
{
list=sdb.ExecuteQueryNullSafe(sql,StartDate,EndDate).ToList();
}
}
捕获(例外e)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(e);
字符串msg=e.Message;
}
退货清单;
}
以下是ExecuteQueryNullSafe:
internal static IEnumerable<TResult> ExecuteQueryNullSafe<TResult>(this System.Data.Linq.DataContext context,
string command, params object[] parameters)
{
var list = new List<object>();
var listVals = new List<bool>();
for (int x = 0; x < parameters.Count(); x++)
{
if (parameters[x] == null || parameters[x] is System.DBNull)
{
command = command.Replace("{" + x + "}", "NULL");
listVals.Add(false);
}
else
{
list.Add(parameters[x]);
listVals.Add(true);
}
}
int nextId = 0;
for (int i = 0; i < listVals.Count; i++)
{
var isUsed = listVals[i];
if (!isUsed)
continue;
if (nextId != i)
command = command.Replace("{" + i.ToString() + "}", "{" + nextId.ToString() + "}");
nextId++;
}
return context.ExecuteQuery<TResult>(command, list.ToArray());
}
内部静态IEnumerable ExecuteQueryNullSafe(此System.Data.Linq.DataContext上下文,
字符串命令,参数对象[]参数)
{
var list=新列表();
var listVals=新列表();
对于(int x=0;x
现在,如果我为方法提供了完全相同的日期,那么返回的列表在Total列中有值。我不明白为什么查询在SQL中运行,但从C代码调用时不提供值。您可以尝试使用SqlParameter。它可能是这样的:
int rowsAffected;
string sql = "EXEC stp_GetSupportTicketMetrics_ByDateRange @StartDate, @EndDate";
List<SqlParameter> parms = new List<SqlParameter>
{
// Create parameters
new SqlParameter { ParameterName = "@StartDate", Value = StartDate },
new SqlParameter { ParameterName = "@EndDate", Value = EndDate }
};
rowsAffected = _db.Database.ExecuteSqlRaw(sql, parms.ToArray());
int行受影响;
字符串sql=“EXEC stp\u GetSupportTicketMetrics\u ByDateRange@StartDate,@EndDate”;
列表参数=新列表
{
//创建参数
新的SqlParameter{ParameterName=“@StartDate”,Value=StartDate},
新的SqlParameter{ParameterName=“@EndDate”,Value=EndDate}
};
rowsAffected=_db.Database.ExecuteSqlRaw(sql,parms.ToArray());
C#中的NULL和DB中的NULL是两个不同的东西。如果C#中的值为NULL,则需要传递DBNULL。看到这个:@Brad,对不起,我该如何设置日期时间?StartDate到DBNull?这个时间?StartDate=DBNull。值不起作用。;您没有将StartDate设置为DBNull.Value,而是将DBNull.Value传递给存储的进程。类似于StartDate.HasValue的内容?StartDate:DBNull.Value
,EndDate也是如此。@insane_开发者-谢谢,但合并给我的错误是“无法确定条件表达式的类型,因为System.DateTime?和System.DBNull之间没有隐式转换”,这要感谢你们两位,但传递的是DBNull”list=sdb.ExecuteQueryNullSafe(sql,DBNull.Value,DBNull.Value).ToList();”返回相同问题的相同结果,因此DBNull似乎不是问题所在。
int rowsAffected;
string sql = "EXEC stp_GetSupportTicketMetrics_ByDateRange @StartDate, @EndDate";
List<SqlParameter> parms = new List<SqlParameter>
{
// Create parameters
new SqlParameter { ParameterName = "@StartDate", Value = StartDate },
new SqlParameter { ParameterName = "@EndDate", Value = EndDate }
};
rowsAffected = _db.Database.ExecuteSqlRaw(sql, parms.ToArray());