简体   繁体   中英

Entity Framework get by weeknumber query

I'm creating an application for a sportsclub. On the homepage I want to show an overview of al the games that are going to be played this week. The problem I'm facing is that on the application layer (c#) I've set my first day of the week on Monday. SQL Server thinks my first day of the week is on Sunday. SQL Server is wrong. How can tell my query that the first day of the week is Monday? Below you can find my code.

public static class DateTimeExtensions
{   
    // Extension method to get the weeknumber from a date
    public static int Weeknumber(this DateTime date)
    {
        var cal = System.Globalization.DateTimeFormatInfo.CurrentInfo.Calendar;
        return cal.GetWeekOfYear(date, 
                      System.Globalization.CalendarWeekRule.FirstDay, DayOfWeek.Monday);
    }
}

To fetch the games, I use the following query:

var weeknumber = DateTime.Now.Weeknumber();
var games = db.Games
              .Where(x => SqlFunctions.DatePart("week", x.Date) == weeknumber)
              .ToList();

Thanks for the suggestions but I did it my own way. Below you can find the way I did it.

First, I made 2 extension methods on the DateTime object:

public static class DateTimeExtensions
{
    public static DateTime StartOfWeek(this DateTime dt, DayOfWeek startOfWeek = DayOfWeek.Monday)
    {
        int diff = dt.DayOfWeek - startOfWeek;
        if (diff < 0)
        {
            diff += 7;
        }

        return dt.AddDays(-1 * diff).Date;
    }
    public static DateTime EndOfWeek(this DateTime dt, DayOfWeek endOfWeek = DayOfWeek.Sunday)
    {
        if (dt.DayOfWeek == endOfWeek)
        {
            return dt.Date.Date.AddDays(1).AddMilliseconds(-1);
        }
        else
        {
            var diff = dt.DayOfWeek - endOfWeek;
            return dt.AddDays(7 - diff).Date.AddDays(1).AddMilliseconds(-1);
        }
    }
}

I used those methods to get a range in the query:

var start = DateTime.Now.StartOfWeek();
var end = DateTime.Now.EndOfWeek();
var games = db.Games
            .Where(x => x.Date >= start && x.Date <= end )
            .OrderBy(x => x.Team.MinAge)
            .ToList();

I used this way so I wont be dependent on database functions. Also I think it is a good thing that my application logic is actually in the application. The database shouldn't care what dates are the start and end date for a week.

You can change the first day of the week by the t-SQL statement SET DATEFIRST . For Monday this is:

SET DATEFIRST 1;

Note however, that this change is scoped to a connection, so you either have to set it each time EF opens a connection, or set the connection culture to have a different default for the first day of the week. For more background, see How to Set DateFirst SQL Function Return for a SQL Server Database Scope Permanent

You could also subtract 1 day from x.Date before taking the date part. If you were unable to adjust the database to do so. This brings Sunday back to the previous week and makes Monday the first day.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM