none
Linq中的字符转日期问题!!! RRS feed

  • 问题

  • IQueryable<ListForOpenTransactionVM2> localDB = null;
    ....... 
     IFormatProvider ifp = new CultureInfo("zh-CN", true);
    DateTime tempStartDate = DateTime.ParseExact(querystartDate,"yyyy-MM",ifp); //开始年月
    DateTime tempEndDate = DateTime.ParseExact(queryendDate,"yyyy-MM", ifp);//结束年月
    
    localDB = localDB.Where(x => DateTime.ParseExact(x.OpenDateYM,"yyyy-MM", ifp) >= tempStartDate && DateTime.ParseExact(x.OpenDateYM, "yyyy-MM", ifp) <= tempEndDate);
    
    提示无法调用DateTime.ParseExact函数,之前我根据日期字段的年日部分做了分组(OpenDateYM,字符型,类似2017-06 ),现在 我需要根据页面的起始日期(也是年月)来做限定查询。


    • 已编辑 icod 2017年7月12日 13:00 ss
    2017年7月12日 12:48

答案

  •  DateTime tempStartDate = DateTime.ParseExact(querystartDate, "yyyy-MM", ifp);
                        DateTime tempEndDate = DateTime.ParseExact(queryendDate, "yyyy-MM", ifp);
     
                        if (tempStartDate > tempEndDate)
                        {
                            return Content("起始日期要小于终止日期!");
                        }

    我是怀疑:你的StartDate和EndDate转化的时候没有dd,HH,MM和SS。如果你要查询一个范围内的时间,应该类似这样的东西:

    Select * from xxx where [datetimefield] >= '2017/07/01 00:00:00' and [datetimefield] <='2017/07/02/ 23:59:59'

    建议您:对转化后的StartDateTime和EndDateTime做时分秒等参数补充(不要取默认值)

    或许你可以尝试一下SQL日期范围查询,你就知道我是什么意思了哦。


    ASP.NET Forum
    StackOverFlow
    FreeRice Donate
    Issues to report




    • 已编辑 ThankfulHeart 2017年7月19日 9:12
    • 已标记为答案 icod 2017年7月25日 9:27
    2017年7月19日 9:11

全部回复

  • System.NotSupportedException:“LINQ to Entities 不识别方法“System.DateTime ParseExact(System.String, System.String, System.IFormatProvider)”,因此该方法无法转换为存储表达式。”
    2017年7月12日 13:00
  • 改写成下面的试下

    DateTime openDate= DateTime.ParseExact(x.OpenDateYM, "yyyy-MM", ifp);

    localDB = localDB.Where(x => openDate>= tempStartDate && openDate<= tempEndDate);


    专注于.NET ERP/CRM开发框架,C/S架构,SQL Server + ORM(LLBL Gen Pro) + Infragistics WinForms

    2017年7月13日 0:12
  • Hi icod,

    >>System.NotSupportedException:“LINQ to Entities 不识别方法“System.DateTime ParseExact(System.String, System.String, System.IFormatProvider)”,因此该方法无法转换为存储表达式。”

    根据你的错误信息,是在EF 映射成SQL语句时不支持C# 方法导致的。你可以先把数据导入内存,然后在内存中过滤。 请参考下面的代码。

     string querystartDate = "2015-05";
                string queryendDate = "2017-07";
    
                CultureInfo provider = CultureInfo.InvariantCulture;
    
                IFormatProvider ifp = new CultureInfo("zh-CN", true);
                DateTime tempStartDate = DateTime.ParseExact(querystartDate, "yyyy-MM", ifp); //开始年月
                DateTime tempEndDate = DateTime.ParseExact(queryendDate, "yyyy-MM", ifp);//结束年月
    
                IQueryable<ListForOpenTransactionVM2> localDB = null;
    
                using (var db = new Model1())
                {
                    localDB = db.ListForOpenTransactionVM2;
    
                    var result = localDB.ToList().Where(x => DateTime.ParseExact(x.OpenDateYM, "yyyy-MM", ifp) >= tempStartDate && DateTime.ParseExact(x.OpenDateYM, "yyyy-MM", ifp) <= tempEndDate);
    
                    }

    Best regards,

    Cole Wu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2017年7月13日 5:13
    版主
  • 你好,由于外出,没来的及试,这样的话是不是就无法利用延时查询的好处了?因为这个查询真好是个动态查询,它还会检查是否有别的查询条件,如果有,还会在这个基础上再次查询。另外

    http://www.itdos.com/CSharp/20150408/0127321.html 这里提到了 linq/EF/lambda 比较字符串日期时间大小

    可我改用后总是查询不到结果,不知为什么?

    localDB = localDB.Where(x => x.OpenDateYM.CompareTo( querystartDate ) >= 0 && x.OpenDateYM.CompareTo( queryendDate ) <= 0);


    2017年7月14日 3:46
  • @Shuanghua Li

    这第一句 就应该不能运行吧? DateTime openDate= DateTime.ParseExact(x.OpenDateYM, "yyyy-MM", ifp);

    x.OpenDateYM 这里的x没有上下文

    2017年7月14日 3:50
  • 请问DbFunctions有解吗?具体怎么用
    2017年7月14日 23:02
  • icod:

    1)使用ParseExact必须做到被转换的字符串表示形式的格式必须与指定的格式完全匹配。请确认是完全匹配的。

    >>2)System.NotSupportedException:“LINQ to Entities 不识别方法“System.DateTime ParseExact(System.String, System.String, System.IFormatProvider)”,因此该方法无法转换为存储表达式。”

    因为LINQ不能全部转化成为正常可以被识别的SQL。所以建议您写一个View或者存储过程,然后传入参数进行查询。

    3)x.OpenDateYM.CompareTo( querystartDate ):这样写法是两个字符串比较,字符串比较显然结果不完全和DateTime比较一致,所以建议你两个都转化成字符串后进行比较。


    ASP.NET Forum
    StackOverFlow
    FreeRice Donate
    Issues to report



    2017年7月15日 3:53
  • 我看了下,似乎 用  DbFunctions.CreateDateTim 函数
    下面是主要的代码,先根据OpenDate字段的年月,以及部门分组,再动态查询

    //dynamic Query
                    localDB = (from o in db.tz_OpenTransactions
                               group o by new { o.UID, OpenDateYM = o.OpenDate.Year + "-" + o.OpenDate.Month } into g
                               orderby g.Key.UID, g.Key.OpenDateYM descending
                               select new ListForOpenTransactionVM2
                               {
                                   UID = g.Key.UID,
                                   OpenDateYM = g.Key.OpenDateYM,
                                   CountOT = g.Count(),
                                   Account = db.Accounts.FirstOrDefault(a => a.ID == g.Key.UID)
                               }).Take(12);
     
                    if (!string.IsNullOrEmpty(querystartDate) && !string.IsNullOrEmpty(queryendDate))
                    {
                        IFormatProvider ifp = new CultureInfo("zh-CN", true);
                        DateTime tempStartDate = DateTime.ParseExact(querystartDate, "yyyy-MM", ifp);
                        DateTime tempEndDate = DateTime.ParseExact(queryendDate, "yyyy-MM", ifp);
     
                        if (tempStartDate > tempEndDate)
                        {
                            return Content("起始日期要小于终止日期!");
                        }
     
                        localDB.Where(x => DbFunctions.CreateDateTime(Int32.Parse(x.OpenDateYM.Split('-')[0]), Int32.Parse(x.OpenDateYM.Split('-')[1]), 1, 0, 0, 0) >= tempStartDate && DbFunctions.CreateDateTime(Int32.Parse(x.OpenDateYM.Split('-')[0]), Int32.Parse(x.OpenDateYM.Split('-')[1]), 1, 0, 0, 0) <= tempEndDate);
                    }

     使用了CreateDateTime函数,选择起止年月,点击查询,数据还是没有变化,这是生产的sql

    {SELECT TOP (12) 
        [Project2].[UID] AS [UID], 
        [Project2].[C1] AS [C1], 
        [Project2].[C2] AS [C2], 
        [Project2].[ID] AS [ID], 
        [Project2].[SimpleName] AS [SimpleName], 
        [Project2].[FullName] AS [FullName], 
        [Project2].[Password] AS [Password], 
        [Project2].[RoleType] AS [RoleType]
        FROM ( SELECT 
            [Distinct1].[UID] AS [UID], 
            [Distinct1].[C1] AS [C1], 
            [Limit1].[ID] AS [ID], 
            [Limit1].[SimpleName] AS [SimpleName], 
            [Limit1].[FullName] AS [FullName], 
            [Limit1].[Password] AS [Password], 
            [Limit1].[RoleType] AS [RoleType], 
            (SELECT 
                COUNT(1) AS [A1]
                FROM [dbo].[tz_OpenTransactions] AS [Extent3]
                WHERE ([Distinct1].[UID] = [Extent3].[UID]) AND (([Distinct1].[C1] = (CASE WHEN (DATEPART (year, [Extent3].[OpenDate]) IS NULL) THEN N'' ELSE  CAST( DATEPART (year, [Extent3].[OpenDate]) AS nvarchar(max)) END + N'-' + CASE WHEN (DATEPART (month, [Extent3].[OpenDate]) IS NULL) THEN N'' ELSE  CAST( DATEPART (month, [Extent3].[OpenDate]) AS nvarchar(max)) END)) OR (([Distinct1].[C1] IS NULL) AND (CASE WHEN (DATEPART (year, [Extent3].[OpenDate]) IS NULL) THEN N'' ELSE  CAST( DATEPART (year, [Extent3].[OpenDate]) AS nvarchar(max)) END + N'-' + CASE WHEN (DATEPART (month, [Extent3].[OpenDate]) IS NULL) THEN N'' ELSE  CAST( DATEPART (month, [Extent3].[OpenDate]) AS nvarchar(max)) END IS NULL)))) AS [C2]
            FROM   (SELECT DISTINCT 
                [Extent1].[UID] AS [UID], 
                CASE WHEN (DATEPART (year, [Extent1].[OpenDate]) IS NULL) THEN N'' ELSE  CAST( DATEPART (year, [Extent1].[OpenDate]) AS nvarchar(max)) END + N'-' + CASE WHEN (DATEPART (month, [Extent1].[OpenDate]) IS NULL) THEN N'' ELSE  CAST( DATEPART (month, [Extent1].[OpenDate]) AS nvarchar(max)) END AS [C1]
                FROM [dbo].[tz_OpenTransactions] AS [Extent1] ) AS [Distinct1]
            OUTER APPLY  (SELECT TOP (1) [Extent2].[ID] AS [ID], [Extent2].[SimpleName] AS [SimpleName], [Extent2].[FullName] AS [FullName], [Extent2].[Password] AS [Password], [Extent2].[RoleType] AS [RoleType]
                FROM [dbo].[Accounts] AS [Extent2]
                WHERE [Extent2].[ID] = [Distinct1].[UID] ) AS [Limit1]
        )  AS [Project2]
        ORDER BY [Project2].[UID] ASC, [Project2].[C1] DESC}

    请问高手,哪里有问题,急急急!!!

    2017年7月19日 9:04
  •  DateTime tempStartDate = DateTime.ParseExact(querystartDate, "yyyy-MM", ifp);
                        DateTime tempEndDate = DateTime.ParseExact(queryendDate, "yyyy-MM", ifp);
     
                        if (tempStartDate > tempEndDate)
                        {
                            return Content("起始日期要小于终止日期!");
                        }

    我是怀疑:你的StartDate和EndDate转化的时候没有dd,HH,MM和SS。如果你要查询一个范围内的时间,应该类似这样的东西:

    Select * from xxx where [datetimefield] >= '2017/07/01 00:00:00' and [datetimefield] <='2017/07/02/ 23:59:59'

    建议您:对转化后的StartDateTime和EndDateTime做时分秒等参数补充(不要取默认值)

    或许你可以尝试一下SQL日期范围查询,你就知道我是什么意思了哦。


    ASP.NET Forum
    StackOverFlow
    FreeRice Donate
    Issues to report




    • 已编辑 ThankfulHeart 2017年7月19日 9:12
    • 已标记为答案 icod 2017年7月25日 9:27
    2017年7月19日 9:11