Reputation: 3180
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
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
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
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