代码之家  ›  专栏  ›  技术社区  ›  Andrew Shepherd

linq-distinct()如果使用扩展方法,则返回不同的值

  •  1
  • Andrew Shepherd  · 技术社区  · 15 年前

    我有一个Linq查询,它试图获取表中所有日期的所有不同月份。

    我使用distinct()扩展方法实现了这个功能。然后,我使用扩展方法提取月份,使其更具可读性。然后它停止返回不同的结果。

    有人能帮我弄清楚这里发生了什么事吗?

    顺便说一句,如果有人能告诉我最好的方法来获得不同的月份,那也不错。但更重要的是,我要明白为什么会失败。

    这是密码。

    static class DcUtils
    {
         public static DateTime GetMonth(this Timesheet_Entry entry)
        {
            DateTime dt = new DateTime(
                                         entry.Entry_Start_DateTime.Year,
                                         entry.Entry_Start_DateTime.Month, 
                                         1
                                      );
            return dt;
        }
    }
    
    
    
    public class Demo
    {
        public DemonstrateBug()
        {
            TimesheetDataClassesDataContext dc = new TimesheetDataClassesDataContext();
        /////////////////////////////////
        //// Here are the queries and their behaviours
        var q1 = (
                    from ts
                    in dc.Timesheet_Entries
                    select new DateTime(ts.Entry_Start_DateTime.Year, ts.Entry_Start_DateTime.Month, 1)
                 ).Distinct();
        // This returns 3 (which is what I want)
        int lengthQuery1 = q1.Count();  
    
        // And now for the bug!
    
        var q2 = (
                     from ts
                     in dc.Timesheet_Entries
                     select ts.GetMonth()
                 ).Distinct(); 
            // This returns 236 (WTF?)
            int lengthQuery2 = q2.Count();
        }
    }
    
    2 回复  |  直到 13 年前
        1
  •  1
  •   Daniel Brückner    15 年前

    new DateTime()

    DISTINCT

    context
        .Timesheet_Entries
        .Select(tse => tse.GetMonth())
        .Distinct()
    

    context
        .Timesheet_Entries
        .Distinct()
        .Select(tse => tse.GetMonth())
    

    Distinct() ToList()

        2
  •  1
  •   Andrew Shepherd    13 年前

    var q1 = (                
                from ts                
                in dc.Timesheet_Entries                
                select new DateTime(ts.Entry_Start_DateTime.Year,
                                    ts.Entry_Start_DateTime.Month, 
                                    1)             
              ).Distinct();
    

    System.DateTime

         SELECT DISTINCT 
                 [t1].[value]
           FROM (
               SELECT 
                    CONVERT(
                              DATETIME, 
                              CONVERT(
                                        NCHAR(2), 
                                        DATEPART(
                                                 Month, 
                                                 [t0].[Entry_Start_DateTime]
                                                 )
                                      ) 
                                        + (''/'' + (CONVERT(NCHAR(2), @p0) 
                                        + (''/'' + CONVERT(NCHAR(4), 
                                                          DATEPART(
                                                               Year, 
                                                               [t0].[Entry_Start_DateTime]
                                                                  )
                                                           )
                                           ))), 101
                                 ) AS [value]
                 FROM [dbo].[Timesheet_Entry] AS [t0]
              ) AS [t1]
    

        var q2 = (                 
                     from ts                 
                     in dc.Timesheet_Entries                 
                     select ts.GetMonth()             
                 ).Distinct(); 
    

    SELECT DISTINCT 
          [t0].[Timesheet_Entry_ID], 
          [t0].[Entry_Start_DateTime], 
          [t0].[Entry_End_DateTime], 
          [t0].[Task_Description], 
          [t0].[Customer_ID]
    FROM [dbo].[Timesheet_Entry] AS [t0]
    

    leaky abstraction