【问题标题】:Return list using select new in LINQ在 LINQ 中使用 select new 返回列表
【发布时间】:2020-07-14 22:50:51
【问题描述】:

这是我的方法,它给了我错误。

public List<Project> GetProjectForCombo()
{
    using (MyDataContext db = new MyDataContext (DBHelper.GetConnectionString()))
    {
        var query = from pro in db.Projects
                    select new { pro.ProjectName, pro.ProjectId };

        return query.ToList();
    }
}

如果我用这个来改变它:

public List<Project> GetProjectForCombo()
{
    using (MyDataContext db = new MyDataContext (DBHelper.GetConnectionString()))
    {
        var query = from pro in db.Projects
                    select pro;

        return query.ToList();
    }
}

然后它可以正常工作,没有错误。

能否请您告诉我如何才能只返回ProjectIdProjectNam

【问题讨论】:

  • 那里的列表是什么?编辑:现在你已经说清楚了;)
  • (请注意,编辑修订似乎暗示我在代码中添加了&lt;Project&gt;,但问题是初始代码包含在&lt;pre&gt;标签中,而不是缩进,删除了尖括号)

标签: c# linq


【解决方案1】:

方法不能返回匿名类型。它必须与方法返回类型中定义的类型相同。检查 GetProjectForCombo 的签名并查看您指定的返回类型。

创建一个具有所需属性的类 ProjectInfo,然后在新表达式中创建 ProjectInfo 类型的对象。

class ProjectInfo
{
   public string Name {get; set; }
   public long Id {get; set; }
}

public List<ProjectInfo> GetProjectForCombo()
{
    using (MyDataContext db = new MyDataContext (DBHelper.GetConnectionString()))
    {
        var query = from pro in db.Projects
                    select new ProjectInfo(){ Name = pro.ProjectName, Id = pro.ProjectId };

        return query.ToList();
    }
}

【讨论】:

  • 嗨,哈桑,感谢您的回复,这真的很有帮助。我必须知道,在不创建新类的情况下,我们也可以获得所需的功能。这样好吗?这对我来说很好。 public List GetProjectForCombo() { using (MyDataContext db = new MyDataContext (DBHelper.GetConnectionString())) { var query = from pro in db.Projects select new Project(){ ProjectName = pro.ProjectName, ProjectId = pro.项目编号 };返回查询.ToList(); } }
  • 它有效但不正确。您向被调用者承诺整个对象,但您只提供其中的部分信息。只有方法的实现才能揭示出糟糕设计的真相。
【解决方案2】:
public List<Object> GetProjectForCombo()
{
   using (MyDataContext db = new MyDataContext (DBHelper.GetConnectionString()))
   {
     var query = db.Project
     .Select<IEnumerable<something>,ProjectInfo>(p=>
                 return new ProjectInfo{Name=p.ProjectName, Id=p.ProjectId);       

     return query.ToList<Object>();
   }

}

【讨论】:

  • query.ToList();为我工作了来自 linq 查询的集合列表。这会从 select new {} 中投射整个对象。谢谢。
【解决方案3】:

你不能从一个类中返回匿名类型...(嗯,你可以,但你必须先将它们转换为对象,然后在另一端使用反射来再次获取数据)所以你必须创建一个包含数据的小类。

class ProjectNameAndId
{
    public string Name { get; set; }
    public string Id { get; set; }
}

然后在你的 LINQ 语句中:

select new ProjectNameAndId { Name = pro.ProjectName, Id = pro.ProjectId };

【讨论】:

  • 只是一个简短的注释ProjectNameAndId 不是一个好的类名:)
  • 是的....我只是很快地写了它。我并没有在想一个好的班级名称。
  • 我知道这是吹毛求疵,但 SO 问题往往会成为有价值的谷歌资源,并认为世界将从我的小评论中受益 :)
【解决方案4】:
public List<Object> GetProjectForCombo()
{
    using (MyDataContext db = new MyDataContext (DBHelper.GetConnectionString()))
     {
         var query = from pro in db.Projects
                     select new {pro.ProjectName,pro.ProjectId};

         return query.ToList<Object>();
    }
}

【讨论】:

  • 你也可以使用无名类,在这种情况下会返回 Object 类型。
【解决方案5】:

试试这个解决方案吧

     public List<ProjectInfo> GetProjectForCombo()
      {
    using (MyDataContext db = new MyDataContext 
    (DBHelper.GetConnectionString()))
         {
        return  (from pro in db.Projects
                    select new { query  }.query).ToList();
        }
      }

【讨论】:

    【解决方案6】:

    返回的是一个匿名类型,所以创建一个包含 2 个字段的新类

    class BasicProjectInfo {
       string name;
       string id;
    }
    

    并返回new BasicProjectInfo(pro.ProjectName, pro.ProjectId);。在这种情况下,您的方法将返回 List&lt;BasicProjectInfo&gt;

    【讨论】:

    • ..只是一个不会编译的快速说明,那里没有定义构造函数。更好的选择就像 Colin Mackay 的:new BasicProjectInfo { name = pro.ProjectName
    【解决方案7】:

    您的方法的返回值必须是List&lt;Project&gt;

    使用select new,您正在创建一个匿名类型的实例,而不是Project

    【讨论】:

    • 请问为什么要使用select new创建实例?
    • @CYB: select new 用于当您希望查询创建某个类的新实例而不是简单地获取源项时。它允许您创建完全不同的类的实例,甚至是像 OP 一样的匿名类。对于像 LINQ-to-Entities 这样的 LINQ 提供程序,投影到匿名类的新实例意味着它可以发出一个 SQL 查询,该查询只获取在 select 语句中使用的列,而不是获取所有列。
    • @CYB:在 OP 的示例中,第一个 sn-p 将创建一个类似于 SELECT [ProjectName],[ProjectId] FROM [Projects] 的 SQL 查询,而第二个需要构造一个完整的 Project 实例并将使用类似 @987654329 的东西@。如果您不需要给定查询的所有属性,您可以通过仅选择您需要的属性来保存一堆数据库操作。 OP 的问题的唯一问题是您不能从方法返回匿名类,而是必须创建一个新类(例如 ProjectInfo like suggested)。
    • 非常感谢。我明白了。
    【解决方案8】:

    你可以这样做:

    class ProjectInfo
    {
        public string Name {get; set; }
        public long Id {get; set; }
    
        ProjectInfo(string n, long id)
        {
            name = n;   Id = id;
        }
    }
    
    public List<ProjectInfo> GetProjectForCombo()
    {
        using (MyDataContext db = new MyDataContext (DBHelper.GetConnectionString()))
        {
             var query = from pro in db.Projects
                        select new ProjectInfo(pro.ProjectName,pro.ProjectId);
    
             return query.ToList<ProjectInfo>();
        }
    }
    

    【讨论】:

    【解决方案9】:

    您正在创建一种新类型的对象,因此它是匿名的。你可以返回一个动态。

    public dynamic GetProjectForCombo()
    {
        using (MyDataContext db = new MyDataContext (DBHelper.GetConnectionString()))
        {
            var query = from pro in db.Projects
                    select new { pro.ProjectName, pro.ProjectId };
    
            return query.ToList();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多