72

This is my method which gives me error.

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

If i change it with this:

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

        return query.ToList();
    }
}

Then it works fine with no errors.

Can you please let me know that how I can return only ProjectId and ProjectNam?

GEOCHET
  • 21,119
  • 15
  • 74
  • 98
Sami
  • 3,956
  • 9
  • 37
  • 52
  • what is the List there ? edit : now you have made it clear ;) – Illuminati Jun 16 '11 at 09:58
  • 1
    (note that the edit revision seem to imply that I added `` in the code, but the problem was that initial code was enclosed in `
    ` tags, instead being indented, which removed angle brackets)
    – vgru Jun 16 '11 at 10:03

9 Answers9

140

Method can not return anonymous type. It has to be same as the type defined in method return type. Check the signature of GetProjectForCombo and see what return type you have specified.

Create a class ProjectInfo with required properties and then in new expression create object of ProjectInfo type.

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();
    }
}
Muhammad Hasan Khan
  • 34,648
  • 16
  • 88
  • 131
  • 2
    Hi Hassan, Thanks for your reply this is really helpfull. I have to know that without creating new class we can also get the required functionality. Is this fine? this works for me fine. 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.ProjectId }; return query.ToList(); } } – Sami Jun 16 '11 at 10:12
  • 5
    It works but its incorrect. You're promising the whole object to the callee but you're only giving partial information in it. Only the implementation of the method reveals the truth which is bad design. – Muhammad Hasan Khan Jun 16 '11 at 10:15
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>();
   }

}

JWP
  • 6,672
  • 3
  • 50
  • 74
  • 2
    query.ToList(); worked for me for list of collections from linq query. This cast whole objects from select new {}. Thank you. – daremachine Oct 01 '14 at 16:08
7

You cannot return anonymous types from a class... (Well, you can, but you have to cast them to object first and then use reflection at the other side to get the data out again) so you have to create a small class for the data to be contained within.

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

Then in your LINQ statement:

select new ProjectNameAndId { Name = pro.ProjectName, Id = pro.ProjectId };
Colin Mackay
  • 18,736
  • 7
  • 61
  • 88
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>();
    }
}
2

try this solution for me its working

     public List<ProjectInfo> GetProjectForCombo()
      {
    using (MyDataContext db = new MyDataContext 
    (DBHelper.GetConnectionString()))
         {
        return  (from pro in db.Projects
                    select new { query  }.query).ToList();
        }
      }
Martin Chinome
  • 431
  • 5
  • 17
1

What is being returned is an anonymous type so create a new class with 2 fields

class BasicProjectInfo {
   string name;
   string id;
}

and return new BasicProjectInfo(pro.ProjectName, pro.ProjectId);. You method in this case will return a List<BasicProjectInfo>

sh_kamalh
  • 3,853
  • 4
  • 38
  • 50
  • ..and just a quick note that won't compile, there's no constructor defined there. The better option would be like Colin Mackay's: `new BasicProjectInfo { name = pro.ProjectName ` etc – Kieren Johnstone Jun 16 '11 at 10:03
1

Your method's return value has to be a List<Project>.

Using select new you are creating an instance of an anonymous type, instead of a Project.

vgru
  • 49,838
  • 16
  • 120
  • 201
  • May I ask why we should use `select new` to create an instance ? – CYB Feb 23 '14 at 09:17
  • @CYB: `select new` is used when you want your query to create new instances of a certain class, instead of simply taking source items. It allows you to create instances of a completely different class, or even an anonymous class like in OP's case. For a LINQ provider like LINQ-to-Entities, projecting to a new instance of an anonymous class means that it can issue an SQL query which only fetches columns which are used inside the select statement, instead of fetching all columns. – vgru Feb 24 '14 at 10:56
  • @CYB: in OP's example, first snippet will create an SQL query similar to `SELECT [ProjectName],[ProjectId] FROM [Projects]`, while the second one needs to construct an entire `Project` instance and will use something like `SELECT * FROM [Projects]`. If you don't need all properties from a given query, you can save a bunch of DB operations by selecting only the properties you need. The only problem with OP's question is that you cannot return an anonymous class from a method, but instead have to create a new one (e.g. `ProjectInfo` [like suggested](http://stackoverflow.com/a/6370057/69809)). – vgru Feb 24 '14 at 11:01
  • Thanks a lot. I've understood it. – CYB Feb 25 '14 at 05:44
0

You can do it as following:

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>();
    }
}
Husam Hilal
  • 107
  • 1
  • 1
  • This won't work since only parameterless constructors and initializers are supported by linq to entities (e.g see http://stackoverflow.com/questions/3571084/only-parameterless-constructors-and-initializers-are-supported-in-linq-to-entiti) – Yaur May 14 '13 at 21:10
-2

You're creating a new type of object therefore it's anonymous. You can return a dynamic.

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();
    }
}
nib_alejo
  • 1
  • 1