【问题标题】:MVC model coding with table model and controller带有表模型和控制器的 MVC 模型编码
【发布时间】:2017-02-07 14:10:00
【问题描述】:

您好我这里有一些编码问题,我想做的是基于输入SYSID,从表中查找名称列表,仅用于测试目的。

型号:

public DbSet<firsttest> firsttests { get; set; }

表格:

  [Table("FirstTest")]
    public class firsttest
    { 
        public firsttest(){}

        [Column("sysId")]
        public long SysId { get; set; }
        public string Name { get; set; }
    }

控制器:

    [Authorize]
    [Route("api/FirstTest/{SysId}")]
    public List<String> Name(long SYSID)
    {
        using (AContext db = new AContext())
        {
            var query = db.firsttests.Where(a => 1 == 1);
            if (!String.IsNullOrEmpty(SYSID.ToString()))
            {
                query = query.Where(a => a.SysId.Equals(SYSID)).Select(a => a.Name);
            }
            return query.ToList();
        }
    }

错误是: 无法将类型 System.Linq.Iqueryable(string) 隐式转换为 System.Linq.Iqueryable(Model.firsttest)

知道如何修改代码吗?

【问题讨论】:

    标签: c# asp.net-mvc linq


    【解决方案1】:

    这一行

    var query = db.firsttests.Where(a =&gt; 1 == 1);

    返回 firsttest 实体的 IQueryable 集合。所以变量query的类型是IQueryable&lt;firsttest&gt;因为类型推断

    但稍后,当您选择 Name 属性时,您会尝试为该变量设置不同的类型 (IQueryable&lt;string&gt;)。

    query = query.Where(a => a.SysId.Equals(SYSID)).Select(a => a.Name);
    

    这就是您收到此编译错误的原因。

    字符串空或空检查也没有意义。 long 值不可为空。因此,您需要有一个有效的数字 long 值才能使路由正常工作。因此,只需在 where 子句中使用参数即可。

    [Route("api/FirstTest/{SysId}")]
    public List<String> Name(long SysId)
    { 
       using (var db = new AContext())
       {
         return db.firsttests   // here the type is IQueryable<firsttest>
                  .Where(a => a.SysId.Equals(SysId)) 
                  .Select(a => a.Name) // here the type is IQueryable<string>
                  .ToList();  // here the type of List<string>
       }
    }
    

    【讨论】:

    • 所以我唯一的选择是在return 行之后添加select?是否有任何显式转换方法我必须从 IQueryable 显式转换为 IQueryable
    • 您可以选择并将其保存在变量中并返回,或者像我一样简单地在一行中执行。最终编译器会对其进行优化,并生成类似于 one liner 生成的代码。
    • 您的代码对我来说解释得很好,只是好奇,没有针对这一行的显式转换? query = query.Where(a =&gt; a.SysId.Equals(SYSID)).Select( a =&gt; a.Name),它将为我将 IQueryable 转换为 IQueryable
    • 没有。您不能将 firsttest 的集合转换为这样的字符串集合。您可以将值设置为不同的变量(var nameList=query.Where(a =&gt; a.SysId.Equals(SYSID)).Select( a =&gt; a.Name)。然后在调用 ToList() 后返回它,因为您的方法返回类型是 List。
    • 我明白了,感谢您的详细回答和解释^ ^
    【解决方案2】:

    试试这个。

    [Authorize]
    [Route("api/FirstTest/{SysId}")]
    public List<String> Name(long SYSID)
    {
        using (SpaContext db = new SpaContext())
        {
            var query = db.firsttests.Where(a => 1 == 1);
            if (!String.IsNullOrEmpty(SYSID.ToString()))
            {
                query = query.Where(a => a.SysId.Equals(SYSID));
            }
            return query.Select(a => a.Name).ToList();
        }
    }
    

    【讨论】:

      【解决方案3】:

      您可以在 if 块中过滤结果,然后在返回 List&lt;string&gt; 之前进行投影,例如:

      if (!String.IsNullOrEmpty(SYSID.ToString()))
      {
          query = query.Where(a => a.SysId.Equals(SYSID)); // only filter here
      }
      return query.Select(a => a.Name).ToList(); // now project the result finally
      

      您看到的这种行为是因为var 在 C# 中的工作方式的性质。

      当您编写 var query = db.firsttests.Where(a =&gt; 1 == 1); 时,变量 query 现在是 IQueryable&lt;Model.firsttest&gt; 类型,现在在代码中,您无法将不同类型的引用分配给变量 query 不同类型的引用,在您的项目后结果将变成System.Linq.Iqueryable&lt;string&gt;

      您可以阅读以下内容更详细地了解它:

      https://msdn.microsoft.com/en-us/library/bb384061.aspx

      What does "var" mean in C#?

      【讨论】:

      • 这对我有用!但是为什么我不能像我的代码一样在return 之前指定select?我需要显式转换方法吗?
      • 这是因为当您编写 var query = db.firsttests.Where(a =&gt; 1 == 1); 时,query 现在是强类型的 IQueryable&lt;Model.firsttest&gt; 而不是在代码中您无法分配不同类型的查询引用,在您的查询中将变为 @987654336 @
      猜你喜欢
      • 2013-06-26
      • 1970-01-01
      • 2011-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-02
      • 2012-05-03
      • 1970-01-01
      相关资源
      最近更新 更多