c# - 转换日期时转换失败 - linq2sql ExecuteQuery

标签 c# linq datetime linq-to-sql executequery

这是我的代码片段:

        #region Validate and prepare parameters
        if (month > 12)
        {
            throw new ArgumentException("Value of 'month' could not be greater than 12.");
        }

        int yearEnd = year;
        int monthEnd = 0;
        if (month != 12)
        {
            monthEnd = month + 1;
        }
        else
        {
            monthEnd = 1;
            yearEnd = year + 1;
        }
        #endregion

        MyModelDataContext context = new MyModelDataContext();

        string sql =
            @"select SUM(ORDERQTY * MULTIPLIER) AS VOL_USD
                from Executions with (nolock)
                where TRANSACTTIME >= '{0}-{1}-01 00:00:00'
                    and TRANSACTTIME < '{2}-{3}-01 00:00:00'
                    and MTCONTEXT in (5,6)
                    and ORDERQTY > 0
                    AND SOURCE = 'INTMT'
                    and LEFT(SYMBOL, 3) = 'USD'";

        decimal usd___Sum = context.ExecuteQuery<decimal>(sql, year, month, yearEnd, monthEnd).First();

我遇到了异常:

Conversion failed when converting date and/or time from character string.

当我调用ExecuteQuery 方法时。 year 的值为 2013,month 的值为 9。我做错了什么?

提前致谢。

最佳答案

您正在将字符串与日期进行比较,迫使数据库“猜测”正确的格式是什么。您使用的格式不是 ISO 格式,因此数据库假定您使用与其排序规则匹配的格式。我敢打赌你使用 LATIN1 或类似的东西。

不是传递整数,然后将它们转换为字符串,例如 TRANSACTTIME >= '{0}-{1}-01 00:00:00',而是传递日期:

 var startDate=new DateTime(year,month,1);
 var endDate=new DateTime(yearEnd,monthEnd,1);

 string sql =
        @"select SUM(ORDERQTY * MULTIPLIER) AS VOL_USD
            from Executions with (nolock)
            where TRANSACTTIME >= {0}
                and TRANSACTTIME < {1}
                and MTCONTEXT in (5,6)
                and ORDERQTY > 0
                AND SOURCE = 'INTMT'
                and LEFT(SYMBOL, 3) = 'USD'";

decimal usd___Sum = context.ExecuteQuery<decimal>(sql, startDate,endDate).First();

更新

正如 Ovidiu 所建议的,参数替换在字符串内部不起作用,因此即使我们为 @p0、@p1 参数提供值,'@p0-@p1-01' 也将保持不变。我们需要通过连接每个部分在字符串外部创建日期。

在 SQL Server 2012 中,我们有另一个选项 DATETIMEFROMPARTS .我们可以从它的部分创建日期,例如:

 string sql =
        @"select SUM(ORDERQTY * MULTIPLIER) AS VOL_USD
            from Executions with (nolock)
            where TRANSACTTIME >= DATETIMEFROMPARTS({0},{1},1,0,0,0,0)
            ..."

尽管传递实际日期仍然更可取

关于c# - 转换日期时转换失败 - linq2sql ExecuteQuery,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19831592/

相关文章:

c# - 在 Rx 中对数组元素进行分组

c# - Controller 中的 Ninject 注入(inject)为空

c# - Xamarin Forms IOS 打开 PDF

c# - Linq 按多列分组并在 group by 子句之前从表中获取额外值

java - java中的日期时间转换

c# - 在 C# 中将列添加到数据表?

c# - 方法 'System.Linq.Queryable.SelectMany System.Linq.IQueryable 的类型参数

c# - 确保 IQueryable<T>.Where() 运行 SQL 查询而不是在内存中过滤

Javascript 返回两个日期之间的天数、小时数、分钟数、秒数

python - 使用日期时间的 UTC 到 CST 转换不正确