C# 如何对数据库中未存储的字段进行排序
我有一个asp.net mvc站点,无法对模型中需要时计算的字段进行排序C# 如何对数据库中未存储的字段进行排序,c#,asp.net-mvc,linq,razor,C#,Asp.net Mvc,Linq,Razor,我有一个asp.net mvc站点,无法对模型中需要时计算的字段进行排序 private decimal _total = -1; public decimal Total { get { if (_total < 0) { _total = get_total(TableId); } return _tot
private decimal _total = -1;
public decimal Total
{
get
{
if (_total < 0)
{
_total = get_total(TableId);
}
return _total;
}
}
private decimal get_total(int id)
{
....Many Calcs
}
我发现了一些类似的问题,但我就是不知道该如何排序
还有我的控制器。为了清晰起见,我试着把它编辑下来
public ActionResult Index(string sortOrder)
{
ViewBag.CurrentSort = sortOrder;
ViewBag.Total = sortOrder == "total" ? "total_desc" : "total";
var records = from u in db.Records.Include(t => t.User).Where(t => t.Active == true)
select u;
switch (sortOrder)
{
case "total":
records = db.Records.OrderBy(u => u.Total).Where(t => t.Active == true);
break;
case "rating_desc":
records = db.Records.OrderByDescending(u => u.Total).Where(t => t.Active == true);
break;
default:
records = db.Records.OrderBy(u => u.Title).Where(t => t.Active == true);
break;
}
return View(records.ToList());
}
在尝试按此属性排序之前,请尝试调用ToList()
方法,因为这无法转换为SQL
语句
//我假设当前您的查询是这样的
DbContext.SomeEntity.Where(…).OrderBy(e=>e.Total);
//调用.ToList()后,可以在内存中对数据进行排序(而不是在db中)
DbContext.SomeEntity.Where(…).ToList().OrderBy(e=>e.Total);
更新:问题是,首先用此行声明
记录变量:
var records = from u in db.Records.Include(t => t.User).Where(t => t.Active == true) select u;
因此,记录
变量的类型将是System.Linq.IQueryable
,这就是为什么在开关情况下“需要”使用.AsQueryable()强制转换的原因
此外,初始值将始终在switch语句中被重写,因此完全没有必要像当前那样初始化它
你应该做什么:
public ActionResult Index(string sortOrder)
{
/* ViewBag things */
IEnumerable<Record> records =
db
.Records
.Include(record => record.User)
.Where(record => record.Active)
.ToList(); // At this point read data from db into memory
// Total property cannot be translated into an SQL statement.
// That's why we call it on memory objects instead of DB entities.
switch (sortOrder)
{
case "total":
records = records.OrderBy(record => record.Total);
break;
case "rating_desc":
records = records.OrderByDescending(record => record.Total);
break;
default:
records = records.OrderBy(record => record.Title);
break;
}
return View(records.ToList());
}
公共操作结果索引(字符串排序器)
{
/*取景袋*/
可数记录=
分贝
.记录
.Include(record=>record.User)
.Where(record=>record.Active)
.ToList();//此时,将数据从数据库读取到内存中
//Total属性无法转换为SQL语句。
//这就是为什么我们对内存对象而不是DB实体调用它。
开关(分拣机)
{
案例“总计”:
records=records.OrderBy(record=>record.Total);
打破
案例“评级描述”:
records=records.OrderByDescending(record=>record.Total);
打破
违约:
records=records.OrderBy(record=>record.Title);
打破
}
返回视图(records.ToList());
}
我需要将我的查询转换为IQueryable,因此这里是更新的开关:
switch (sortOrder)
{
case "total":
records = db.Records.Where(t => t.Active == true).AsQueryable().OrderBy(u => u.Total));
break;
case "rating_desc":
records = db.Records.Where(t => t.Active == true).AsQueryable.OrderByDescending(u => u.Total).;
break;
default:
records = db.Records.Where(t => t.Active == true).AsQueryable.OrderBy(u => u.Title).;
break;
}
显示对数据进行排序的查询。不显示实际排序的代码,也不显示添加此Total
属性的代码。从外观上看,我猜您是通过一个分部类将其添加到EF实体中的。更改查询后,我现在遇到以下错误:错误12无法隐式地将类型“System.Linq.iorderenumerable”转换为“System.Linq.IQueryable”。存在明确的转换(您是否缺少演员阵容?)有任何想法?在我的回答中添加了有关您转换问题的更新。感谢Gabor的更新。这样做的唯一真正好处是避免强制转换每个switch语句吗?我只是好奇,因为我希望很快实现延迟加载,我相信ienumerable不支持这一点,但我再次将其抛出——我只是在做同样的事情——我是c#的新手。将记录的类型
变量显式设置为ienumerable
的好处是我必须调用ToList()
在对结果列表进行排序后,只需执行一次。如果我使用了List
,那么我应该在每个switch语句中调用ToList()
。但是:当我初始化records
变量时,我必须调用ToList()
,因为它会迭代resultset,从而导致查询被转换为SQL语句并执行。以便从数据库中读取数据并加载到内存中。此步骤需要能够按Total
属性排序,因为它无法转换为SQL。此外,您可以在此处阅读有关List
vsIEnumerable
的延迟加载:添加了有关转换问题的我的答案的更新。你不需要像我更新的答案中描述的那样施法。
switch (sortOrder)
{
case "total":
records = db.Records.Where(t => t.Active == true).AsQueryable().OrderBy(u => u.Total));
break;
case "rating_desc":
records = db.Records.Where(t => t.Active == true).AsQueryable.OrderByDescending(u => u.Total).;
break;
default:
records = db.Records.Where(t => t.Active == true).AsQueryable.OrderBy(u => u.Title).;
break;
}