Search code examples
c#linq-to-entitiesanonymous-objects

LINQ to Entity - using anonymous object in a query


I am trying to write LINQ2Entity query which will return only 3 columns from the table and then to set the result as a DataSource of a ComboBox.

The problem I have is this. First - to select all from the table I use a service like this:

IList<SoleColor> soles = SoleColorService.All().ToList();

Which is ready to be set as a DataSource for the ComboBox which waits data of this type. However because I want to choose anonymous object to store only 3 of the columns that the query result I modified my query like this :

IList<SoleColor> soles = SoleColorService.All()
                    .GroupBy(t => t.Sole.Code)
                    .Select(g => new
                    {
                        SoleCode = g.Key,
                        SoleName = g.Select(t => t.Sole.Name),
                        SoleId   = g.Select(t => t.SoleID)
                    }); 

Which leads to marking the .Selectas error with the following text "Cannot implicitly convert type System.Linq.IQueryable to System.Collections.Generic.IList". If I change IList<SoleColor> soles = to var soles = it's fine but then there's a problem with assigning anonymous type like a DataSource, but I think this can be fixed in the query so I get the right type there. Also at some point I have to add something like First() or FirstOrDafult() to y query, because I have many records with the same SoleCode and I want to keep only one for each unique SoleCode.


Solution

  • First: How to only get one result per group I already showed you in your previous question. Combined with an anonymous type this would look like the following:

    SoleColorService.All()
                    .GroupBy(t => t.Sole.Code)
                    .Select(g => g.First())
                    .Select(x => new
                    {
                        SoleCode = x.Sole.Code,
                        SoleName = x.Sole.Name),
                        SoleId   = x.SoleID)
                    }); 
    

    Second: If you need to return the result of this query in a strong typed manner from your method you can't use an anonymous type. You will have to create a named type and use that instead:

    public class SoleModel
    {
        private readonly string _code;
        private readonly string _name;
        private readonly int _id;
    
        public SoleModel(string code, string name, int id)
        {
            _code = code;
            _name = name;
            _id = id;
        }
    
        public string Code { get { return _code; } }
        public string Name { get { return _name; } }
        public int Id { get { return _id; } }
    }
    
    SoleColorService.All()
                    .GroupBy(t => t.Sole.Code)
                    .Select(g => g.First())
                    .Select(x => new SoleModel(x.Sole.Code, x.Sole.Name x.SoleID)); 
    

    Third: Assigning a list of anonymous types to a datasource should work.

    var result = SoleColorService.All()
                                 .GroupBy(t => t.Sole.Code)
                                 .Select(g => g.First())
                                 .Select(x => new
                                 {
                                     SoleCode = x.Sole.Code,
                                     SoleName = x.Sole.Name),
                                     SoleId   = x.SoleID)
                                 }); 
    someControl.DataSource = result;