关于向ASP.NET MVC应用程序添加基本排序/过滤,我正在关注this tutorial。
问题是,我实际上并不想按模型的属性排序,而是从模型的string
属性派生int
。
下面的ExceptionModel
有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());
}
我当前的exceptions.OrderBy(e => db.Patients.Find(e.PatientID).Name)
尝试会抛出此运行时异常:
System.ArgumentException:在类型'System.Data.Entity.DbSet`1 [EDB.Models.ClientModel]'上声明的方法'EDB.Models.ClientModel Find(System.Object [])'无法使用实例调用输入'System.Data.Entity.Core.Objects.ObjectQuery`1 [EDB.Models.ClientModel]'
编辑:
我被告知我应该使用实体导航属性。现在我只是有这样的事情:
public class ExceptionModel
{
public int ID { get; set; }
public int PatientID { get; set; }
public int ClientID { get; set; }
public int PhysicianID { get; set; }
}
public class PatientModel // Never need to go from Patient to Exception, so I typically access this with db.Patients.Find(exception.PatientID)
{
public int ID { get; set; }
}
public class ClientModel
{
public int ID { get; set; }
public List<int> PhysicianIDs { get; set; } // One client has many physicians
public string PhysicianStore { get { /* parse list to string */ } set { /* parse string to list and store in PhysicianIDs */ } }
}
public class PhysicianModel
{
public int ID { get; set; }
public int ClientID { get; set; } // Each physician maps to one client
}
我不明白我应该改变什么来解决这个问题。
答案 0 :(得分:0)
Laurent Lequenne的评论是准确的。您正在使用实体。您尝试按客户端计算的值进行排序。实体无法将此计算转换为SQL Server语句,因此它会抛出异常。
关于它没有表现的评论也是如此。您可以使用ToList
检索结果并继续处理,不会抛出任何异常,但是对于大型结果集会变得很难看;你想把那种处理推到一个细分市场。
答案 1 :(得分:0)
要访问相关数据,您应使用可翻译的联接。我认为你不需要Exceptions
没有匹配的Clients
等来排序,所以我使用了内连接。如果这样做,您可以使用左外连接。
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());
}