使用LINQ中的select new返回列表

72

这是我的方法,但它给我报错。

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


什么是List?编辑:现在你已经让它清楚了 ;) - Illuminati
1
(请注意,编辑修订似乎暗示我在代码中添加了“<Project>”,但问题是初始代码被包含在<pre>标签中,而不是缩进,因此删除了尖括号) - vgru
9个回答

140

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

创建一个具有所需属性的ProjectInfo类,然后在new表达式中创建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();
    }
}

2
嗨,哈桑,谢谢你的回复,这真的很有帮助。我必须知道,我们可以在不创建新类的情况下获得所需的功能。这样可以吗?这对我来说很好用。public List<Project> GetProjectForCombo() { using (MyDataContext db = new MyDataContext(DBHelper.GetConnectionString())) { var query = from pro in db.Projects select new Project(){ ProjectName = pro.ProjectName, ProjectId = pro.ProjectId }; return query.ToList(); }} - Sami
5
它能够运行,但是不正确。你向调用者承诺了整个对象,但实际上只提供了部分信息。只有方法的实现揭示了真相,这是一个糟糕的设计。 - Muhammad Hasan Khan

13
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>();
   }

}


2
query.ToList<Object>(); 对于从linq查询中的集合列表对我很有用。这将从select new {}中转换整个对象。谢谢。 - daremachine

7

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

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

然后在您的LINQ语句中:

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

1
只是一个小提示,ProjectNameAndId 不是一个好的类名 :) - Kieren Johnstone
1
是的...我只是快速地写了它。我没有太认真考虑一个好的类名。 - Colin Mackay
3
我知道这可能是吹毛求疵,但是Stack Overflow的问题往往会成为有价值的可搜索资源,我想世界会受益于我的这条小评论 :) - Kieren Johnstone

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。 - user2383325

2

请尝试这个解决方案,它有效。

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

1
返回的是匿名类型,因此创建一个具有2个字段的新类。
class BasicProjectInfo {
   string name;
   string id;
}

并返回 new BasicProjectInfo(pro.ProjectName, pro.ProjectId);。在这种情况下,您的方法将返回一个List<BasicProjectInfo>


只是一个快速的提示,这段代码无法编译,因为没有定义构造函数。更好的选择是像Colin Mackay所示的那样:new BasicProjectInfo { name = pro.ProjectName 等。 - Kieren Johnstone

1

你的方法返回值必须是一个 List<Project>

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


我可以问一下为什么我们应该使用 select new 来创建一个实例吗? - CYB
@CYB:当您希望查询创建某个类的新实例而不仅仅是获取源项时,可以使用select new。它允许您创建完全不同类的实例,甚至是像OP案例中的匿名类。对于像LINQ-to-Entities这样的LINQ提供程序,投影到匿名类的新实例意味着它可以发出仅获取在选择语句中使用的列的SQL查询,而不是获取所有列。 - vgru
@CYB:在OP的示例中,第一个代码片段将创建类似于SELECT [ProjectName],[ProjectId] FROM [Projects]的SQL查询,而第二个代码片段需要构造整个Project实例,并将使用类似于SELECT * FROM [Projects]的语句。如果您不需要给定查询中的所有属性,则可以通过仅选择所需的属性来节省大量的DB操作。 OP问题的唯一问题是您无法从方法返回匿名类,而必须创建一个新类(例如ProjectInfo 建议使用)。 - vgru
非常感谢。我已经理解了。 - CYB

0
你可以按照以下步骤完成:
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>();
    }
}

这不会起作用,因为linq to entities仅支持无参数构造函数和初始化器(例如,请参见https://dev59.com/HXA65IYBdhLWcg3w5zHB)。 - Yaur

-2
你正在创建一种新类型的对象,因此它是匿名的。你可以返回一个动态值。
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();
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接