Alex
Alex

Reputation: 38529

Selecting a new type from linq query

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.

Upvotes: 4

Views: 18774

Answers (2)

Enigmativity
Enigmativity

Reputation: 117084

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

Upvotes: 6

Tommy Grovnes
Tommy Grovnes

Reputation: 4156

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

Upvotes: 0

Related Questions