I have an Entity Framework model (some properties have been excluded to keep it simple):
public class Media { public int MediaID { get; set; } public ICollection<Track> Tracks { get; set; } public ICollection<RelatedMedia> RelatedMedias { get; set; } } I then have my DbContext:
public class MediaServiceContext : DbContext { public DbSet<Media> Medias { get; set; } } I can then retrieve data using the following, and it works great:
public Media Media_Get(int id) { using (MediaServiceContext mc = new MediaServiceContext()) { return mc.Medias.Include("Tracks").Include("RelatedMedias").Single(m => m.MediaID == id); } } My question is, I may not want to load one or both of the related entities in some cases, depending on which part of my application is calling this code; how can I make the Includes dynamic?
I have tried this:
public Media Media_Get(int id, bool includeRelated, bool includeTracks) { using (MediaServiceContext mc = new MediaServiceContext()) { IQueryable<Media> query = mc.Medias; if (includeRelated) query = query.Include("RelatedMedias"); if (includeTracks) query = query.Include("Tracks"); return query.Single(m => m.MediaID == id); } } ...but I get a 'Specified cast in not valid' exception.
I have also tried this proposed solution, but it produces a 'unable to cast DbQuery to ObjectQuery' exception. Changing the extension method in the linked solution from '(ObjectQuery)source' to '(DbQuery)source' then causes the same 'Specified cast in not valid' exception.
I have hunted high and low for a solution on this but with no luck. Any help would be much appreciated.
Amendment - Here's the stack trace:
at System.Data.SqlClient.SqlBuffer.get_Int64() at lambda_method(Closure , Shaper ) at System.Data.Common.Internal.Materialization.Coordinator.HasNextElement(Shaper shaper) at System.Data.Common.Internal.Materialization.Shaper`1.RowNestedResultEnumerator.MoveNext() at System.Data.Common.Internal.Materialization.Shaper`1.ObjectQueryNestedEnumerator.TryReadToNextElement() at System.Data.Common.Internal.Materialization.Shaper`1.ObjectQueryNestedEnumerator.MoveNext() at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source) at System.Linq.Queryable.SingleOrDefault[TSource](IQueryable`1 source, Expression`1 predicate) at API.Areas.V1.Models.RetailerManager.Media_Get(Int32 id, String retailerKey, Boolean includeLicenses, Boolean includeProperties, Boolean includeRelated, Boolean includeTracks) in C:\Users\garth\Documents\Development\WebApplications\api\Areas\V1\Models\RetailerManager.cs:line 28 at API.Areas.V1.Controllers.RetailerController.Media(Nullable`1 id, String httpVerb, Boolean includeLicenses, Boolean includeProperties, Boolean includeRelated, Boolean includeTracks) in C:\Users\garth\Documents\Development\WebApplications\api\Areas\V1\Controllers\RetailerController.cs:line 25 at lambda_method(Closure , ControllerBase , Object[] ) at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12() at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
Include:query = query.Include(m => m.RelatedMedias);andquery = query.Include(m => m.Tracks);. It should make no difference at runtime but perhaps we see a bit more if it behaves different.