实体框架:无法在计算字段IQueryable上调用.OrderBy

时间:2020-02-23 16:06:42

标签: c# asp.net asp.net-mvc entity-framework entity-framework-6

我目前正在努力弄清楚如何才能通过仅具有吸气剂的字段订购查询。我有一个IQueryable,其构建如下:

var referrals = db.Referrals
                        .Include(x => x.Doctor)
                        .Include(x => x.OfficeLocation)
                        .Where(x => (vm.OfficeLocationSelection == -1 ? true : x.OfficeLocationId == vm.OfficeLocationSelection) &&
                        string.IsNullOrEmpty(vm.SearchTerm) ? true : x.Doctor.Name.ToLower().Contains(vm.SearchTerm.ToLower()))
                        .GroupBy(x => x.Doctor)
                        .Select(x => new ReferralGridRowViewModel
                        {
                            DoctorName = x.Key.Name,
                            January = x.Where(y => y.DoctorId == x.Key.Id && y.Date.Month == 1 && y.Date.Year == DateTime.Now.Year).Count(),
                            February = x.Where(y => y.DoctorId == x.Key.Id && y.Date.Month == 2 && y.Date.Year == DateTime.Now.Year).Count(),
                            March = x.Where(y => y.DoctorId == x.Key.Id && y.Date.Month == 3 && y.Date.Year == DateTime.Now.Year).Count(),
                            April = x.Where(y => y.DoctorId == x.Key.Id && y.Date.Month == 4 && y.Date.Year == DateTime.Now.Year).Count(),
                            May = x.Where(y => y.DoctorId == x.Key.Id && y.Date.Month == 5 && y.Date.Year == DateTime.Now.Year).Count(),
                            June = x.Where(y => y.DoctorId == x.Key.Id && y.Date.Month == 6 && y.Date.Year == DateTime.Now.Year).Count(),
                            July = x.Where(y => y.DoctorId == x.Key.Id && y.Date.Month == 7 && y.Date.Year == DateTime.Now.Year).Count(),
                            August = x.Where(y => y.DoctorId == x.Key.Id && y.Date.Month == 8 && y.Date.Year == DateTime.Now.Year).Count(),
                            September = x.Where(y => y.DoctorId == x.Key.Id && y.Date.Month == 9 && y.Date.Year == DateTime.Now.Year).Count(),
                            October = x.Where(y => y.DoctorId == x.Key.Id && y.Date.Month == 10 && y.Date.Year == DateTime.Now.Year).Count(),
                            November = x.Where(y => y.DoctorId == x.Key.Id && y.Date.Month == 11 && y.Date.Year == DateTime.Now.Year).Count(),
                            December = x.Where(y => y.DoctorId == x.Key.Id && y.Date.Month == 12 && y.Date.Year == DateTime.Now.Year).Count()
                        });

ReferralGridRowViewModel如下所示(注意YearToDate属性):

public class ReferralGridRowViewModel
    {
        public string DoctorName { get; set; }

        public int January { get; set; }

        public int February { get; set; }

        public int March { get; set; }

        public int April { get; set; }

        public int May { get; set; }

        public int June { get; set; }

        public int July { get; set; }

        public int August { get; set; }

        public int September { get; set; }

        public int October { get; set; }

        public int November { get; set; }

        public int December { get; set; }

        public int YearToDate {
            get {
                return (January + February + March + April + May + June + July + August + September + October + November + December);
            }
        }
    }

当我尝试调用以下内容时:

referrals = referrals.OrderByDescending(x => x.YearToDate);

然后我收到以下异常:

LINQ中不支持指定的类型成员'YearToDate' 实体。仅初始化器,实体成员和实体导航 属性。

在此行上实际执行查询时:

referralRows = referrals.Skip(vm.Skip).Take(vm.PageSize).ToList();

我如何才能表现出色?我宁愿不为YearToDate在数据库中添加一列,因为那将是多余的,并且我无法.ToList先进行所有操作,然后再进行排序,因为在db中有数百万条记录,这会对性能造成重大影响

2 个答案:

答案 0 :(得分:0)

您可以仅添加[NotMapped]属性:

using System.ComponentModel.DataAnnotations.Schema;
...

public class ReferralGridRowViewModel
{
    ...

    [NotMapped]
    public int YearToDate {
    get {
      return (January + February + March + April + May + June + July + August + September + October + November + December);
    }
  }
}

它指示EF忽略db端的属性。参见文档:
https://docs.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations.schema.notmappedattribute?view=netframework-4.8

答案 1 :(得分:0)

在选择实际的YearToDate之前,我可以通过检查医生ID和年份的分组来按ReferralGridRowViewModel记录进行排序:

                    var referralsGrouping = db.Referrals
                        .Include(x => x.Doctor)
                        .Include(x => x.OfficeLocation)
                        .Where(x => (vm.OfficeLocationSelection == -1 ? true : x.OfficeLocationId == vm.OfficeLocationSelection) &&
                        string.IsNullOrEmpty(vm.SearchTerm) ? true : x.Doctor.Name.ToLower().Contains(vm.SearchTerm.ToLower()))
                        .GroupBy(x => x.Doctor);

                    if (!string.IsNullOrEmpty(vm.SortColumn))
                    {
                        if (vm.SortColumn == "YearToDate")
                        {
                            if (vm.SortDirection == SortDirectionType.Descending)
                            {
                                referralsGrouping = referralsGrouping.OrderByDescending(x => x.Count(y => y.DoctorId == x.Key.Id && y.Date.Year == DateTime.Now.Year));
                            }
                            else
                            {
                                referralsGrouping = referralsGrouping.OrderBy(x => x.Count(y => y.DoctorId == x.Key.Id && y.Date.Year == DateTime.Now.Year));
                            }
                        }
                    }

                    var referrals = referralsGrouping
                    .Select(x => new ReferralGridRowViewModel
                    {
                        DoctorName = x.Key.Name,
                        January = x.Where(y => y.DoctorId == x.Key.Id && y.Date.Month == 1 && y.Date.Year == DateTime.Now.Year).Count(),
                        February = x.Where(y => y.DoctorId == x.Key.Id && y.Date.Month == 2 && y.Date.Year == DateTime.Now.Year).Count(),
                        March = x.Where(y => y.DoctorId == x.Key.Id && y.Date.Month == 3 && y.Date.Year == DateTime.Now.Year).Count(),
                        April = x.Where(y => y.DoctorId == x.Key.Id && y.Date.Month == 4 && y.Date.Year == DateTime.Now.Year).Count(),
                        May = x.Where(y => y.DoctorId == x.Key.Id && y.Date.Month == 5 && y.Date.Year == DateTime.Now.Year).Count(),
                        June = x.Where(y => y.DoctorId == x.Key.Id && y.Date.Month == 6 && y.Date.Year == DateTime.Now.Year).Count(),
                        July = x.Where(y => y.DoctorId == x.Key.Id && y.Date.Month == 7 && y.Date.Year == DateTime.Now.Year).Count(),
                        August = x.Where(y => y.DoctorId == x.Key.Id && y.Date.Month == 8 && y.Date.Year == DateTime.Now.Year).Count(),
                        September = x.Where(y => y.DoctorId == x.Key.Id && y.Date.Month == 9 && y.Date.Year == DateTime.Now.Year).Count(),
                        October = x.Where(y => y.DoctorId == x.Key.Id && y.Date.Month == 10 && y.Date.Year == DateTime.Now.Year).Count(),
                        November = x.Where(y => y.DoctorId == x.Key.Id && y.Date.Month == 11 && y.Date.Year == DateTime.Now.Year).Count(),
                        December = x.Where(y => y.DoctorId == x.Key.Id && y.Date.Month == 12 && y.Date.Year == DateTime.Now.Year).Count()
                    });

                if (!string.IsNullOrEmpty(vm.SortColumn))
                {
                    if (vm.SortColumn == "DoctorName")
                    {
                        if (vm.SortDirection == SortDirectionType.Descending)
                        {
                            referrals = referrals.OrderByDescending(x => x.DoctorName);
                        }
                        else
                        {
                            referrals = referrals.OrderBy(x => x.DoctorName);
                        }
                    }
                    //other vm sort columns
                }