String based Include
See original GitHub issueIn the older version of EF you were able to do something like, which is useful for dynamic scenarios.
var query = db.CampaignCreatives.AsQueryable();
foreach (string include in includes)
{
query = query.Include(include);
};
Edited July-18 by @rowanmiller
Workaround
Here is some code that adds two string based overloads of Include
.
- One allows you to do EF6 style string includes - such as
context.Blogs.Include("Posts")
andcontext.Blogs.Include("Posts.Author.Photo")
. - The second overload allows you to make use of the C# 6
nameof
feature when including multiple levelscontext.Blogs.Include(nameof(Post.Blog), nameof(Blog.Owner), nameof(Person.Photo))
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
namespace ConsoleApplication5
{
public static class Extensions
{
private static MethodInfo _include = typeof(EntityFrameworkQueryableExtensions)
.GetMethod("Include");
private static MethodInfo _thenIncludeReference = typeof(EntityFrameworkQueryableExtensions)
.GetMethods()
.Where(m => m.Name == "ThenInclude")
.Single(m => m.Name == "ThenInclude" &&
m.GetParameters()
.Single(p => p.Name == "source")
.ParameterType
.GetGenericArguments()[1].Name != typeof(ICollection<>).Name);
private static MethodInfo _thenIncludeCollection = typeof(EntityFrameworkQueryableExtensions)
.GetMethods()
.Where(m => m.Name == "ThenInclude")
.Single(m => m.Name == "ThenInclude" &&
m.GetParameters()
.Single(p => p.Name == "source")
.ParameterType
.GetGenericArguments()[1].Name == typeof(ICollection<>).Name);
public static IQueryable<T> Include<T>(this IQueryable<T> query, string include)
{
return query.Include(include.Split('.'));
}
public static IQueryable<T> Include<T>(this IQueryable<T> query, params string[] include)
{
var currentType = query.ElementType;
var previousNavWasCollection = false;
for (int i = 0; i < include.Length; i++)
{
var navigationName = include[i];
var navigationProperty = currentType.GetProperty(navigationName);
if (navigationProperty == null)
{
throw new ArgumentException($"'{navigationName}' is not a valid property of '{currentType}'");
}
var includeMethod = i == 0
? _include.MakeGenericMethod(query.ElementType, navigationProperty.PropertyType)
: previousNavWasCollection
? _thenIncludeCollection.MakeGenericMethod(query.ElementType, currentType, navigationProperty.PropertyType)
: _thenIncludeReference.MakeGenericMethod(query.ElementType, currentType, navigationProperty.PropertyType);
var expressionParameter = Expression.Parameter(currentType);
var expression = Expression.Lambda(
Expression.Property(expressionParameter, navigationName),
expressionParameter);
query = (IQueryable<T>)includeMethod.Invoke(null, new object[] { query, expression });
if (navigationProperty.PropertyType.GetInterfaces().Any(x => x.Name == typeof(ICollection<>).Name))
{
previousNavWasCollection = true;
currentType = navigationProperty.PropertyType.GetGenericArguments().Single();
}
else
{
previousNavWasCollection = false;
currentType = navigationProperty.PropertyType;
}
}
return query;
}
}
}
Issue Analytics
- State:
- Created 8 years ago
- Comments:20 (5 by maintainers)
Top Results From Across the Web
Can a string-based Include alternative be created in Entity ...
Starting with v1.1.0, the string based include is now part of EF Core, so the issue and the below solution are obsolete. Original...
Read more >EntityFrameworkQueryableExten...
Include <TEntity>(IQueryable<TEntity>, String). Specifies related entities to include in the query results. The navigation property to be included is specified ...
Read more >NET 6 EF Core Load Related Data with Include(), ThenInclude ...
NET Jumpstart Course: https://www.udemy.com/course/net-core-31-web-api-entity-framework-core-jumpstart/?referralCode=CA390CA392FF8B003518 ...
Read more >[Entity Framework] Using Include with lambda expressions
I'm currently working on a project that uses Entity Framework 4. Even though lazy loading is enabled, I often use the ObjectQuery.Include ......
Read more >Connection String in Entity Framework Core
Connection string contain information about the data source that is being connected. This information varies from provider to provider, ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
@eqbalsajadi String-based include was shipped in EF Core 1.1. That stackoverflow is out-of-date.
Worth mentioning using this feature is risky if the include string is an unvalidated input coming from a user. A user can cause EF to query the entire DB and cause a DoS with a single request or cause SqlInjection.