Saturday, December 12, 2009

Entity Framework IEnumerable Lambda Join Sample

I figured this out from a sample, but it wasn't at all clear. The docs provide no sample, and the parameter names are totally confusing. If you're using EF, and you're wondering how the Join IEnumerable extension method works with your entities, here is the simplest example:


var parent_child = entities.Parent.Join

 (

   entities.Child,            // child entity

   parent => parent.ParentId, // function providing parent key

   child => child.ChildId,    // function providing child key

   ( parent, child ) => new   // projection (anonymous object returning what you want)

   {

      ChildId = child.ChildId,

      WhateverElseFromChild = child.WhateverElse,

      WhateverElseFromParent = parent.WhateverElse,

      ParentId = parent.ParentId

   }

       // pc here is anonymous object created above

 ).Where( pc => pc.Condition == "some condition" ).FirstOrDefault();


Tracing this against SqlServer showed very clean SQL. The exact same SQL produced by this linq equivalent:



var parent_child = ( from parent in entities.Parent

                                join child in entities.Child on parent.ParentId equals child.ChildId

                                where parent.Condition == "some condition"

                                select new

                                {

                                        ChildId = child.ChildId,

                                        WhateverElseFromChild = child.WhateverElse,

                                        WhateverElseFromParent = parent.WhateverElse,

                                        ParentId = parent.ParentId

                                }).FirstOrDefault();

2 comments:

Anonymous said...

Note that FirstOrDefault() (and most other 'resolving' LINQ methods) takes a predicate, so you can write:

.Where( pc => pc.Condition == "some condition" ).FirstOrDefault();
as
.FirstOrDefault( pc => pc.Condition == "some condition" );

A bit tidier. Thanks for the article, though.

Brad said...

Agreed; I would always use that form now. I wrote this a very long time ago.