初始化查询

时间:2020-05-05 00:10:04

标签: asp.net-mvc linq

我需要根据参数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);
 }

1 个答案:

答案 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;
    }
}

更新:

显然Forms2019Forms2020返回不同的实体类型,这意味着您不能使用单个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;
    }
}
相关问题