Use C # Func as part of IQueryable without making a memory call

I am trying to create a query that will be executed with the database as IQueryable, and not in memory (IEnumerable).

The query will be used for several different purposes, and each goal has a slightly different way of calculating the property value.

Since I use Func to calculate the total, I get an error message telling me that sql does not know how to deal with the Invoke method of my Func, which is understandable.

To overcome this problem, I had to list the groups in memory by calling ToList (), which is bad for performance.

Is there a way that I can execute this query as IQueryable? Otherwise, they will have to write this query 20 times with calculation deviations

Func<IGrouping<object, MyType>, double?> calculateTotal= (group) => @group.Sum(x => x.PassengerTotal);

Dictionary<object, double?> weekValues = queryable.GroupBy(o => new
               {
                   Year = SqlFunctions.DatePart("yyyy", o.DateCreated),
                   Week = SqlFunctions.DatePart("ww", o.DateCreated),
                   Source = o.SourceId,
               })
               .ToList() //NEED TO REMOVE THIS CALL
               .Select(ac => new WeeklyGraphGroup()
               {
                   Year = ac.Key.Year,
                   Week = ac.Key.Week,
                   SourceId = ac.Key.Source,
                   Total = calculateTotal(ac)
               })
               .ToDictionary(dict =>
                   new
                   {
                       Year = dict.Year,
                       Week = dict.Week,
                       Source = dict.SourceId
                   }, grp => grp.Total);
+4
1

:

public partial class WeeklyGraphGroup
{
    public int ? Year { get; set; }

    public int  ? Week { get; set; }

    public int Source { get; set; }

}

public partial class WeeklyGraphGroup
{
    private int ? _Total;

    public int ? Total
    {


        get
        {


            this._Total = CalculateTotal(this.Year, this.Week, this.Source);

            return this._Total;
        }

    }

    public int ? CalculateTotal(int ? Year, int ? Week, int Source)
    {

        // do your calculation and return the value of total
        // use whatever formula you want here. I guess you are calculating 
        // total based on any of the parameters(year, week or source);

        return value;

    }



}

, :

var list = db.Stores.GroupBy(o => new WeeklyGraphGroup
{
Year = SqlFunctions.DatePart("yyyy", o.DateCreated),
Week = SqlFunctions.DatePart("ww", o.DateCreated),
Source = o.SourceId,
})
.Select ( u => new WeeklyGraphGroup 
{
Year = u.Key.Year,
Week = u.Key.Week,
Source = u.Key.Source
}
).ToList();

+1

Source: https://habr.com/ru/post/1668928/


All Articles