Phill Healey
Phill Healey

Reputation: 3180

LINQ What does 'select new' do?

I've built the following LINQ query

var activeMembers = from m in context.py3_membershipSet
                    join c in context.ContactSet on m.py3_Member.Id equals c.ContactId 
                    where m.statuscode.Value == 1
                    orderby m.py3_name
                    select m;

But I've since seen an example formatted as such:

var contacts =
(
    from c in xrm.ContactSet
    join a in xrm.AccountSet on c.ParentCustomerId.Id equals a.Id
    where a.Name == "Acme Pty Ltd"
    select new
    {
        Name = c.FullName,
        DOB = c.BirthDate,
        Gender = (c.FormattedValues.Contains("gendercode") ? c.FormattedValues["gendercode"] : "Ambiguous")
    }
);

(I realise this is a different set of data) What does the inclusion of the 'select new' actually do in this case?

What are the benefits of it over my example in the first code block?

I realise some might find this a tedious question, but I a want to learn LINQ and need to learn it fast. But I also don't want to run something -that I don't fully understand- on a clients live CRM

Upvotes: 3

Views: 6028

Answers (3)

Steven Wexler
Steven Wexler

Reputation: 17279

You are using the Queryable.Select<TSource, TResult>(IQueryable<TSource>, Expression<Func<TSource, TResult>>) method where ContactSet is the TSource and the of anonymous object return type is the TResult. Your code could also be written as

...Select(r => new { 
                        Name = c.FullName, 
                        DOB = c.BirthDate, 
                        Gender = (c.FormattedValues.Contains("gendercode") ? c.FormattedValues["gendercode"] : "Ambiguous") 
                    })

where the select method is returning a collection of anonymous types.

Also, there is a bit more going on under the hood since it looks like you're querying the database. Your implementation of IQueryable looks at the Select method that you've written, and translates the expression you've provided into valid SQL so that it can retrieve all the necessary information for the anonymous object that you're returning. Notice that I said your implemenation of IQuerable translates the provided expression (not function) into sql. The Select extension method only accepts expressions, not functions because it can't translate functions to sql.

Upvotes: 1

Kittoes0124
Kittoes0124

Reputation: 5080

As previous answers have noted both methods return an anonymous type. To fully answer your question though: "What are the benefits of the second statement over the first?"

The first statement returns all of the fields of m as-is. If you have 7 "columns" then activeMembers will contain all of them and whatever data they contain.

In the second statement you're projecting the results into a custom anonymous object that has only 3 fields. Not only that but you can perform logic on the "source fields" before storing them in the anonymous object. This gives you much of the flexibility of storing them in a container class without you actually having to define that class in code.

You could also do select new SomeClass { } which would project your results into a predefined class container.

The following pseudo-code may or may not be helpful in understanding the difference:

var myQuery = from p in someContext.someTable
              group p by p.someField into g
              select new MyContainer {
                  Field1 = g.Sum(a => a.field1)
                  Field2 = g.Max(a => a.field2)
              };

myQuery in the above is now a collection of MyContainer. If I had omitted the class MyContainer then it would be a collection of an Anonymous Type containing the fields that I specified. Obviously, the difference here is that MyContainer has to be defined elsewhere in your code whereas the anonymous class is built/defined for you at compile time. In:

var myQuery = from p in someContext.someTable
              select p;

myQuery is an anonymous class containing all of the fields and their values in someTable.

Upvotes: 5

Adam Plocher
Adam Plocher

Reputation: 14233

LINQ returns a collection of anonymous objects, either way. select new let's you define the layout of that object and which properties/property names are included in that anonymous object.

You can also use select new ClassName { } to return a list of instances of an entity class that you define.

Upvotes: 5

Related Questions