Print Page | Close Window

options.Include of navigation property collections

Printed From: IdeaBlade
Category: Cocktail
Forum Name: Community Forum
Forum Discription: A professional application framework using Caliburn.Micro and DevForce
Printed Date: 21-Oct-2020 at 8:21pm

Topic: options.Include of navigation property collections
Posted By: KitKat
Subject: options.Include of navigation property collections
Date Posted: 15-May-2013 at 7:05am
How can you accomplish the strongly typed include when you are navigating past a collection of related entities.

In the example below I have had to define one of my includes as a string since Jobs is a RelatedEntityList, and not just a single entity.  Is there some function I am missing that would allow me to strongly type this?

            var punchUser =
                (await _punchUser
                       .FindAsync(e => e.RecordId == punchId 
                           && e.PunchPin == punchPin, 
                           options => 
                                //.Include(user => user.Employee.Jobs)
                                .Include(user => user.Employee.OrgLevel1)
                                .Include(user => user.Employee.OrgLevel2)
                                .Include(user => user.Employee.OrgLevel3)
                                .Include(user => user.Employee.OrgLevel4)
                                .Include(user => user.Employee.OrgLevel5)

Thank you,

Posted By: smi-mark
Date Posted: 15-May-2013 at 9:45am
i wrote an extension method for queries, you could do the same for the options

    public static class EntityQueryExtensions
        public static IEntityQuery<T> IncludePath<T>(this IEntityQuery<T> query, params string[] propertyPaths)
            return query.Include(propertyPaths.Aggregate((a, b) => a + "." + b));

something like this:

.IncludePath(Employee.EntityPropertyNames.Jobs, Job.EntityPropertyNames.LwHrJob)

Posted By: mgood
Date Posted: 15-May-2013 at 11:05am
The extension method is a good idea. Other than that you can't strongly type it because Employee.Jobs.LwHrJob would mean that LwHrJob is a property of the Jobs collection when in fact it is a property of each item in the Jobs collection. You won't get this past the compiler. 

Posted By: stephenmcd1
Date Posted: 15-May-2013 at 12:09pm
I've built a helper class that builds strings such as 'Employee.Jobs.LwHrJob' using strongly typed lambdas.  It's not always the easiest to use but it gets the job done.  And for us, a little bit of annoyance/verbosity when first writing the code is worth it if it saves of from running into problems if the model changes.  An example usage of the helper class would be:
    public void TestBuildPath()
        var actualPath = IncludeHelper
            .Include(user => user.Employee)
            .IncludeMany(employee => employee.Jobs)
            .Include(job => job.Detail)

        Assert.AreEqual("Employee.Jobs.Detail", actualPath);


In this case, the IncludeMany method is the one that is really giving us value because it lets us 'flatten' the collection.

You can get the full code from here: -

Posted By: KitKat
Date Posted: 15-May-2013 at 1:09pm
Thank you all for your responses.

Stephan, this is exactly what I was looking for.  I like to stay as far away from Magic Strings as I can.

Thank you all again,

Posted By: KitKat
Date Posted: 15-May-2013 at 1:12pm
Do you have a license for the code you linked, or is it public domain and free for me to use?

Thank you,

Posted By: stephenmcd1
Date Posted: 15-May-2013 at 2:41pm
I agree - magic strings are asking for trouble.

I've update the code sample to include the - MIT license which as far as I know means you can use it in just about any way you'd like.  I'm not an expert on licensing so if that doesn't work for you, let me know.

Glad the code will work for you!

Print Page | Close Window