C# 如何按集合自身属性以外的其他内容对集合进行排序?

C# 如何按集合自身属性以外的其他内容对集合进行排序?,c#,asp.net-mvc,entity-framework,linq,C#,Asp.net Mvc,Entity Framework,Linq,下面我将向ASP.NET MVC应用程序添加基本排序/筛选 问题是,我实际上不想按模型的属性排序,而是从模型的int属性派生的strings 下面的例外模型有一个ClientID、PatientID和PhysicianID,链接到另一个DbSet中的条目。我需要按条目的名称排序 public ActionResult Index(string sortOrder) { ViewBag.ClientSortParam = System.String.IsNullOrEmpty(sortOr

下面我将向ASP.NET MVC应用程序添加基本排序/筛选

问题是,我实际上不想按模型的属性排序,而是从模型的
int
属性派生的
string
s

下面的
例外模型
有一个
ClientID
PatientID
PhysicianID
,链接到另一个
DbSet
中的条目。我需要按条目的名称排序

public ActionResult Index(string sortOrder)
{
    ViewBag.ClientSortParam = System.String.IsNullOrEmpty(sortOrder) ? "client_desc" : "";
    ViewBag.PatientSortParam = sortOrder == "Patient" ? "patient_desc" : "Patient"; // If sorting by Patient (ascending), flip to patient_desc, otherwise remain
    ViewBag.PhysicianSortParam = sortOrder == "Physician" ? "physician_desc" : "Physician";
    IQueryable<ExceptionModel> exceptions = from e in db.Exceptions
                                            select e; // Select all in table
    switch (sortOrder)
    {
        case "client_desc": // Default is Client ascending, at the bottom
            exceptions = exceptions.OrderByDescending(e => db.Clients.Find(e.ClientID).Name);
            break;

        case "Patient":
            exceptions = exceptions.OrderBy(e => db.Patients.Find(e.PatientID).Name);
            break;
        case "patient_desc":
            exceptions = exceptions.OrderByDescending(e => db.Patients.Find(e.PatientID).Name);
            break;

        case "Physician":
            exceptions = exceptions.OrderBy(e => db.Physicians.Find(e.PhysicianID).Name);
            break;
        case "physician_desc":
            exceptions = exceptions.OrderByDescending(e => db.Physicians.Find(e.PhysicianID).Name);
            break;

        default:
            exceptions = exceptions.OrderBy(e => db.Clients.Find(e.ClientID).Name);
            break;
    }

    return View(exceptions.ToList());
}

我不明白我应该改变什么来解决这个问题。

劳伦特·莱昆恩的评论是准确的。您正在使用实体。您正在尝试按客户端计算的值进行排序。实体无法将此计算转换为SQL Server语句,因此它引发异常


关于它没有被执行的评论也是真实的。您可以使用
ToList
检索结果并继续处理,而不会抛出异常,但如果结果集很大,则会变得很糟糕;您可能希望将这种处理过程推到一个存储过程中。

Laurent Lequenne的评论是准确的。您正在使用实体。您正在尝试按客户端计算的值进行排序。实体无法将此计算转换为SQL Server语句,因此它引发异常


关于它没有被执行的评论也是真实的。您可以使用
ToList
检索结果并继续处理,而不会抛出异常,但如果结果集很大,则会变得很糟糕;您可能希望将这种处理推送到存储过程。

为了访问相关数据,您应该使用可以转换的联接。我假设您不需要对没有匹配的
客户端的
异常进行排序,所以我使用了内部联接。如果这样做,则可以使用左外部联接

public ActionResult Index(string sortOrder) {
    ViewBag.ClientSortParam = System.String.IsNullOrEmpty(sortOrder) ? "client_desc" : "";
    ViewBag.PatientSortParam = sortOrder == "Patient" ? "patient_desc" : "Patient"; // If sorting by Patient (ascending), flip to patient_desc, otherwise remain
    ViewBag.PhysicianSortParam = sortOrder == "Physician" ? "physician_desc" : "Physician";
    IQueryable<ExceptionModel> exceptions = db.Exceptions;

    switch (sortOrder) {
        case "client_desc": // Default is Client ascending, at the bottom
            exceptions = from e in exceptions join c in db.Clients on e.ClientID equals c.ClientID orderby c.Name descending select e;
            break;

        case "Patient":
            exceptions = from e in exceptions join p in db.Patients on e.PatientID equals p.PatientID orderby p.Name select e;
            break;
        case "patient_desc":
            exceptions = from e in exceptions join p in db.Patients on e.PatientID equals p.PatientID orderby p.Name descending select e;
            break;

        case "Physician":
            exceptions = from e in exceptions join p in db.Physicians on e.PhysicianID equals p.PhysicianID orderby p.Name select e;
            break;
        case "physician_desc":
            exceptions = from e in exceptions join p in db.Physicians on e.PhysicianID equals p.PhysicianID orderby p.Name descending select e;
            break;

        default:
            exceptions = from e in exceptions join c in db.Clients on e.ClientID equals c.ClientID orderby c.Name descending select e;
            break;
    }

    return View(exceptions.ToList());
}
公共操作结果索引(字符串排序器){
ViewBag.ClientSortParam=System.String.IsNullOrEmpty(排序器)?“客户端描述”:“;
ViewBag.PatientSortParam=sortOrder==“Patient”?“Patient_desc”:“Patient”//如果按患者排序(升序),则翻转到Patient_desc,否则保留
ViewBag.PhysicianSortParam=sortOrder==“内科医师”?“内科医师描述”:“内科医师”;
IQueryable exceptions=db.exceptions;
开关(分拣机){
案例“client_desc”://默认值为客户端升序,在底部
异常=从异常中的e加入数据库中的c。e.ClientID上的客户端等于c.ClientID orderby c。名称降序选择e;
打破
个案“病人”:
异常=从异常中的e加入数据库中的p。e.PatientID上的患者等于p.PatientID orderby p。名称选择e;
打破
案例“患者描述”:
异常=从异常中的e加入数据库中的p。e.PatientID上的患者等于p.PatientID orderby p。名称降序选择e;
打破
病例“医生”:
异常=从异常中的e加入数据库中的p。e.PhysicianID上的医生等于p.PhysicianID按p排序。名称选择e;
打破
案例“医师描述”:
异常=从异常中的e加入数据库中的p。e.PhysicianID上的医生等于p.PhysicianID按p排序。名称降序选择e;
打破
违约:
异常=从异常中的e加入数据库中的c。e.ClientID上的客户端等于c.ClientID orderby c。名称降序选择e;
打破
}
返回视图(exceptions.ToList());
}

要访问相关数据,应使用可翻译的联接。我假设您不需要对没有匹配的
客户端的
异常进行排序,所以我使用了内部联接。如果这样做,则可以使用左外部联接

public ActionResult Index(string sortOrder) {
    ViewBag.ClientSortParam = System.String.IsNullOrEmpty(sortOrder) ? "client_desc" : "";
    ViewBag.PatientSortParam = sortOrder == "Patient" ? "patient_desc" : "Patient"; // If sorting by Patient (ascending), flip to patient_desc, otherwise remain
    ViewBag.PhysicianSortParam = sortOrder == "Physician" ? "physician_desc" : "Physician";
    IQueryable<ExceptionModel> exceptions = db.Exceptions;

    switch (sortOrder) {
        case "client_desc": // Default is Client ascending, at the bottom
            exceptions = from e in exceptions join c in db.Clients on e.ClientID equals c.ClientID orderby c.Name descending select e;
            break;

        case "Patient":
            exceptions = from e in exceptions join p in db.Patients on e.PatientID equals p.PatientID orderby p.Name select e;
            break;
        case "patient_desc":
            exceptions = from e in exceptions join p in db.Patients on e.PatientID equals p.PatientID orderby p.Name descending select e;
            break;

        case "Physician":
            exceptions = from e in exceptions join p in db.Physicians on e.PhysicianID equals p.PhysicianID orderby p.Name select e;
            break;
        case "physician_desc":
            exceptions = from e in exceptions join p in db.Physicians on e.PhysicianID equals p.PhysicianID orderby p.Name descending select e;
            break;

        default:
            exceptions = from e in exceptions join c in db.Clients on e.ClientID equals c.ClientID orderby c.Name descending select e;
            break;
    }

    return View(exceptions.ToList());
}
公共操作结果索引(字符串排序器){
ViewBag.ClientSortParam=System.String.IsNullOrEmpty(排序器)?“客户端描述”:“;
ViewBag.PatientSortParam=sortOrder==“Patient”?“Patient_desc”:“Patient”//如果按患者排序(升序),则翻转到Patient_desc,否则保留
ViewBag.PhysicianSortParam=sortOrder==“内科医师”?“内科医师描述”:“内科医师”;
IQueryable exceptions=db.exceptions;
开关(分拣机){
案例“client_desc”://默认值为客户端升序,在底部
异常=从异常中的e加入数据库中的c。e.ClientID上的客户端等于c.ClientID orderby c。名称降序选择e;
打破
个案“病人”:
异常=从异常中的e加入数据库中的p。e.PatientID上的患者等于p.PatientID orderby p。名称选择e;
打破
案例“患者描述”:
异常=从异常中的e加入数据库中的p。e.PatientID上的患者等于p.PatientID orderby p。名称降序选择e;
打破
病例“医生”:
异常=从异常中的e加入数据库中的p。e.PhysicianID上的医生等于p.PhysicianID按p排序。名称选择e;
打破
案例“医师描述”:
异常=从异常中的e加入数据库中的p。e.PhysicianID上的医生等于p.PhysicianID按p排序。名称降序选择e;
打破
违约:
异常=从异常中的e加入数据库中的c。e.ClientID上的客户端等于c.ClientID orderby c。名称降序选择e;
打破
}
返回视图(exceptions.ToList());
}

创建导航属性和
OrderBy(e=>e.Patient.Name)
等等。您正在尝试从linq语句创建SQL语句。如果您真的想像这样对列表排序,您需要首先执行SQL语句。。。所以我想你可以先检索异常列表。。。然后您可以使用order.List exceptions=(从db.exceptions中的e选择e).ToList();但这并不是最有效的方法:)@Laurent