我需要根据参数year动态更改表名。例如,在2019年:
var qry= db.Forms2019.Where(x=>x.Active==true).OrderBy(x=>x.Name)
在2020年:
vary qry= db.Forms2020.Where(x=>x.Active==true).OrderBy(x=>x.Name);
所以我正在使用开关盒。我有疑问如何在这里初始化qry?
public ActionResult Index(string year){
var qry=??;
switch(year){
case "2019":
qry=db.Forms2019;
break;
case "2020":
qry=db.Forms2020;
break;
}
return View(qry);
}
答案 0 :(得分:1)
使用switch
很好(这是我的方式),但我会这样做:
(您可以使用 switch-expression 使其更简洁,但这需要C#8.0和.NET Core 3.0,但是您用asp.net-mvc
标记了问题,这意味着可能最迟使用C#7.x(因为ASP.NET MVC不在.NET Core上运行,并且您不能将C#8.0与ASP.NET MVC一起使用)
仅当所有表都包含相同的实体类型(或类型是协变的)时,以下方法才有效:
public async Task<ActionResult> Index( Int32? year ) {
// I assume Forms2019, Forms2020, etc all use the `Form` entity type:
IQueryable<Form> query = this.GetBaseQuery( year ?? DateTime.Utc.Year );
if( query is null )
{
return this.NotFound( message: $"No forms for the year {year} exist." );
}
List<Form> list = await query
.Where( f => f.Active )
.OrderBy( f => f.Name )
.ToListAsync()
.ConfigureAwait(false);
return this.View( model: list );
}
private IQueryable<Form> GetBaseQuery( Int32 year )
{
switch( year )
{
case 2019:
return this.db.Forms2019;
case 2020:
return this.db.Forms2020;
default:
return null;
}
}
显然Forms2019
和Forms2020
返回不同的实体类型,这意味着您不能使用单个IQueryable<Form2019>
变量来保存IQueryable<Form2020>
查询。
解决方案是使用接口-幸运的是,Entity Framework和Linq通常支持此接口:
首先,使用我们要查询的成员定义interface IForm
:
interface IForm
{
Boolean Active { get; }
String Name { get; }
}
partial class Form2019 : IForm
{
}
partial class Form2020 : IForm
{
}
然后将上面的代码更改为此:
public async Task<ActionResult> Index( Int32? year ) {
// I assume Forms2019, Forms2020, etc all use the `Form` entity type:
IQueryable<IForm> query = this.GetBaseQuery( year ?? DateTime.Utc.Year );
if( query is null )
{
return this.NotFound( message: $"No forms for the year {year} exist." );
}
List<IForm> list = await query
.Where( f => f.Active )
.OrderBy( f => f.Name )
.ToListAsync()
.ConfigureAwait(false);
return this.View( model: list );
}
private IQueryable<IForm> GetBaseQuery( Int32 year )
{
switch( year )
{
case 2019:
return (IQueryable<IForm>)this.db.Forms2019; // This works because IQueryable<T> is covariant over T.
case 2020:
return (IQueryable<IForm>)this.db.Forms2020;
default:
return null;
}
}