4

I'm trying to transform some data selected out of a repository using Linq.

My code so far:

Repository<Result> _repository = new Repository<Result>();

var disciplines = _repository.Query()
    .Select(d => new Discipline
    {
        DisciplineCode = d.DisciplineCode,
        Name = d.DisciplineName
    })
    .Distinct()
    .ToList();

Result class looks like:

public class Result
{
    public virtual int ResultId { get; set; }
    public virtual string DisciplineCode { get; set; }
    public virtual string DisciplineName { get; set; }
    public virtual int CompetitorId { get; set; }
    //other stuff
}

When this runs, I get

Unable to determine the serialization information for the expression: < MemberInitExpression >

Any idea what's going wrong?

EDIT:

As per Chris suggestion, I tried the Select after ToList like this:

var disciplines = _repository.Query()
                .Select(d => new
                {
                    DisciplineCode = d.DisciplineCode,
                    Name = d.DisciplineName
                })
                .Distinct()
                .ToList()
                .Select(d => new Discipline { DisciplineCode = d.DisciplineCode, Name = d.Name });

However, this time, similar error, but it's to do with the anonymous type:

Unable to determine the serialization information for the expression: new __AnonymousType(d.DisciplineCode, d.DisciplineName).

EDIT 2:

To clarify, .Query is returning IQueryable
The underlying database is MongoDB (using C# driver)

If I do this:

var disciplines = _repository.Query()
    .Select(d => d.DisciplineName)
    .Distinct()
    .ToList()

It works. By works, I mean I get a distinct list of DisciplineNames

I need to be able to select more properties than just the name however.

Alex
  • 37,502
  • 51
  • 204
  • 332
  • 1
    Could it be that it is trying to put your discipline object into the query to the repository rather than making the query and then transforming it? Try putting the select after the ToList to force it to evaluate the query before you try to do the transform... – Chris Jul 06 '12 at 12:55
  • edited with result of trying that.... – Alex Jul 06 '12 at 13:12
  • What does .Query() do? Is it running a query (or sp?) on the database? – Maarten Jul 06 '12 at 13:13
  • What are you trying to achive with the Distinct when calling it on a reference type? I would expect a reference comparison when testing equality, so you wouldn't achieve a distinct as I think you want it. – Maarten Jul 06 '12 at 13:16
  • Linq2Sql, Linq2Entities, Linq2Objects, Nhibernate.Linq, Interlinq? That is your repository class? – Nikolay Jul 06 '12 at 13:31
  • .Query is returning IQueryable – Alex Jul 06 '12 at 13:37
  • Edited again to clarify @Maarten – Alex Jul 06 '12 at 13:40
  • Can you create a `Repository` or similar so that you have the right type straight off and can just do a distinct to get what you want? The problem seems to be that you can't run the filter you need (grouping by two columns or selecting two columns and distincting) on this query which leads me to think that new query is the only option.... – Chris Jul 06 '12 at 15:18
  • You can try the solution to this question. http://stackoverflow.com/questions/7364354/linq-to-sql-select-distinct-by-multiple-columns-and-return-entire-entity – Maarten Jul 07 '12 at 19:45

2 Answers2

6

I would suspect that your issue is that the MongoDB driver doesn't know how to create a Discipline object (or an anonymous object for that matter).

You need to move out of the the IQueryable<> and into IEnumerable<> to make this work.

Try this:

var disciplines =
    _repository
        .Query()
        .ToArray()
        .Select(d => new Discipline
            {
                DisciplineCode = d.DisciplineCode,
                Name = d.DisciplineName
            })
        .Distinct()
        .ToList();

The .ToArray() is the magic here. Let me know if this works.

You still may have issues with the .Distinct() call working on your custom type, so you may need to try this:

var disciplines =
    _repository
        .Query()
        .ToArray()
        .Select(d => new
            {
                d.DisciplineCode,
                d.DisciplineName
            })
        .Distinct()
        .Select(d => new Discipline
            {
                DisciplineCode = d.DisciplineCode,
                Name = d.DisciplineName
            })
        .ToList();
Enigmativity
  • 113,464
  • 11
  • 89
  • 172
0

Not sure why your first example does not run, it looks Ok, see related question here. Possibly it might be a bug in your db driver ?

You could try using GroupBy to achieve the same result:

    var disciplines = _repository.Query()     
    .GroupBy(d => new Discipline     
        {         
             DisciplineCode = d.DisciplineCode,         
             Name = d.DisciplineName     
        }
    ) 
    .ToList();
Community
  • 1
  • 1
Tommy Grovnes
  • 4,126
  • 2
  • 25
  • 40