Home > Net >  Select data from database where date in current month
Select data from database where date in current month

Time:05-21

I have a button to show me my note's from my database in this month but there is a problem, when I used this LINQ, I got this error

System.InvalidOperationException
The LINQ expression 'DbSet()
.Where(r => r.Date == (Nullable)Convert.ToDateTime(DateTime.Now.Month))' could not be translated.

When I don't convert DateTime.Now.Month to datetime, I got this error too for my below code:

Operator'==' can't be applied to operands of type 'DateTime?' and 'int'

Code:

var z = mydb.ReminderTbls
            .Where(x => x.Date == DateTime.Now.Month);

This is my full code:

var z = mydb.ReminderTbls
            .Where(x => x.Date == Convert.ToDateTime(DateTime.Now.Month));

noteDataGridView.Rows.Clear();

foreach (var item in z)
{
    noteDataGridView.Rows.Add(item.Id, item.Desciption, String.Format("{0:yyyy-MM-dd}", item.Date.Value.GetPdate()));
}

CodePudding user response:

One way to compare months is to take the year,month and scale it so that we have an integer of the format YYYYMM and then a simple arithmetic comparison will work. However for IQueryables this may not work, and for IEnumerables with large datasets this can be slow and using DbFunctions as explained at the end is the best way to do this.

e.g.

{
    int count = 100;
    var sd = DateTime.Now.AddDays(-count);
    var vals = Enumerable.Range(0,count).Select(xx=> new {Date = sd.AddDays(xx)});
    var refdate = DateTime.Now;
    var thisMonth = vals.Where(xx=> (xx.Date.Year*100   xx.Date.Month) == (refdate.Date.Year*100   refdate.Date.Month));
}

With EntityFramework there are also functions that are available that will do this in the database (when using an IQueryable).

var referenceDate = DateTime.Now;
ReminderTbls.AsQueryable().Where(x => DbFunctions.DiffMonths(x.Date, referenceDate) == 0);

[1] As a separate issue all dates in database should be stored in UTC.

CodePudding user response:

You can use begin of month and make comparison which is preferred by databases and uses indexes, if they exist for sure:

var startDate = DateTime.Now.Date;
var startDate = new DateTime(currentDate.Year, currentDate.Month, 1);
var endDate = startDate.AddMonths(1);

var z = mydb.ReminderTbls.Where(x => x.Date >= currentDate && x.Date < endDate);

CodePudding user response:

The issue here is that x.Date appears to be nullable. The error Operator'==' can't be applied to operands of type 'DateTime?' and 'int' states that you're trying to compare a nullable date DateTime? to an int DateTime.Now.Month. So your expression needs to check for null first, and if it's not null then cast the DateTime? to a DateTime.

So, suppose your class has a property like this:

class Record
{
    public DateTime? Date { get; set; }
}

And we mock the list like so:

var mockReminderTbls = new Record[] 
{ 
    new Record(){Date = null },
    new Record(){Date = new DateTime(2022, 5, 1 )},
};

... then to query it you could use this expression:

 var z = mockReminderTbls.Where(x=>
            (x.Date != null) && 
            ((DateTime)x.Date).Month == DateTime.Now.Month);

Console.WriteLine($"Returned {z.Count()} records.");

enter image description here

Give that a try and see if it helps.

EDIT: Let me add that I reproduced the problem and this is the cure.

enter image description here

  • Related