How to query and calculate dates in the where clause of a LINQ statement?

空扰寡人 提交于 2019-12-11 19:37:45

问题


I am having trouble with the following piece of code. Before I paste it, Let me give a bit of history on what should happen.

I have a model containing 2 fields of interest at the moment, which is the name of the order the customer placed, and the date at which he/she placed it. A pre-calculated date will be used to query the dateplaced field (and should only query the dates , and not the time). The query counts the amount of duplicates that occur in the MondayOrder field, and groups them together. Now , when I exclude the where clause which should query the dates, the query runs great. However, The goal of this query is to count the amount of orders for the following week based on the date the order has been placed.

List<string> returnlist = new List<string>();
DateTime dt = getNextWeekMondaysDate().Date;
switch (day)
{
    case DayOfWeek.Monday: 
    {
        var CountOrders =
           from x in Data.EntityDB.Orders 
           group x by x.MondayOrder into m 
           let count = m.Count() 
           select new
           {
               MondayOrderItem = m.Key, Amount = count 
           };

        foreach (var item in CountOrders)
        {
            returnlist.Add(item.MondayOrderItem + " : " +
               item.Amount);
        }
    }
    break;

The getNextWeekMondaysDate() method has an overload which I can use, where if I supply it a date, it will get the following Monday's date from the parameter given. The problem is though, LINQ does not accept queries such as the following:

var CountOrders =
    from x in Data.EntityDB.Orders 
    where getNextWeekMondaysDate(x.DatePlaced.Value).Date == dt
    group x by x.MondayOrder into m 
    let count = m.Count() 
    select new { MondayOrderItem = m.Key, Amount = count };

This is exactly what I must achieve. Is there any workaround for this situation?

UPDATE

Here is the exception I get when I try the 2nd query.

LINQ to Entities does not recognize the method 'System.DateTime getNextWeekMondaysDate(System.DateTime)' method, and this method cannot be translated into a store expression.


回答1:


You cannot do this directly, as user-defined method calls cannot be translated to SQL by the EF query provider. The provider recognizes a limited set of .NET methods that can be translated to SQL and also a number of canonical functions as well. Anything that cannot be expressed using these methods only is off-limits unless you write your own query provider (which is only theoretically an option).

As a practical workaround, you can calculate an appropriate range for x.DatePlaced.Value in code before the query and then use specific DateTime values on the where clause.

As an intellectual exercise, note that this method is recognized by the query provider and can be used as part of the expression. So this abomination should work too:

var CountOrders =
    from x in Data.EntityDB.Orders 
    where EntityFunctions.AddDays(
        x.DatePlaced.Date.Value, 
        (9 - DateAndTime.DatePart(DateInterval.WeekDay, x.DatePlaced.Value)) % 7)
        .Date == dt
    group x by x.MondayOrder into m 
    let count = m.Count() 
    select new { MondayOrderItem = m.Key, Amount = count };



回答2:


Linq to Entities doesn't know how to convert arbitrary C# methods into SQL - it's not possible in general.

So, you have to work with the methods it does understand.

In this case, you could do something like this:

DateTime weekBegin = CalculateWeekBegin( dt );
DateTime weekEnd = CalculateWeekEnd( dt );

var CountOrders =
  from x in Data.EntityDB.Orders 
  where x.DatePlaced.Value >= weekBegin && x.DatePlaced.Value < weekEnd
  group x by x.MondayOrder into m 
  let count = m.Count() 
  select new { MondayOrderItem = m.Key, Amount = count });


来源:https://stackoverflow.com/questions/10717177/how-to-query-and-calculate-dates-in-the-where-clause-of-a-linq-statement

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!