-
Notifications
You must be signed in to change notification settings - Fork 244
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to use filtered include in specification? #67
Comments
Are you on .NET 5? This feature has only just been added to EF Core: I haven't tried it yet, myself. |
What you're requiring is the Regardless of that, for now, we have no support for it in this package. All We need to refactor and add support, but honestly, I have no bright idea of how to do it. In order to implement it, we have to store the Include/ThenInclude expressions, and that's quite a big issue. We have no easy way to store multi-level Includes as expressions. EF internally implements this by building up the IQueryable incrementally, just adding up each next expression. We have no luxury of doing it since we'll have to reference EFCore in the base package. |
The |
Indeed the evaluation of the specification and the translation is done in the plugin package. Let me be more specific. You can store the first level public static IIncludableSpecificationBuilder<TEntity, TProperty> ThenInclude<TEntity, TPreviousProperty, TProperty>(
this IIncludableSpecificationBuilder<TEntity, TPreviousProperty> previousBuilder,
Expression<Func<TPreviousProperty, TProperty>> thenIncludeExpression)
where TEntity : class
{
var propertyName = (thenIncludeExpression.Body as MemberExpression)?.Member?.Name;
previousBuilder.Aggregator.AddNavigationPropertyName(propertyName);
return new IncludableSpecificationBuilder<TEntity, TProperty>(previousBuilder.Specification, previousBuilder.Aggregator);
} Here So, as a solution, on each level, we're extracting the property name and concatenating it to the navigation path. Each I'm out of ideas here :( |
So unfortunately for a person like me that is completely based his project on this package and has implemented eshopOnWeb DDD style in his project layers (Core and Infrastructure) there is no option available right now. true? Is there a way to use new .NET 5 feature to limit my includes and not totally revamp entire relevant project parts? |
You always can create custom repositories for these specific scenarios and write your queries using EF directly. You can totally do DDD without this feature, it's not a deal breaker. As a matter of fact, in terms of DDD, I would suggest to try to avoid this feature. If you're using aggregates, you want to get the whole aggregate, not only portion of the children. If you have loaded only part of it, you will end up with implicit rules in your code. The rest of the code will have to be aware and keep track what is loaded. Imagine using This feature is handy for reading and reporting tasks. In those cases, not necessarily you want to include your domain model in the process, thus you don't need specifications either. |
I should thank you for for your time, its appreciated. |
@ardalis will decide on that. I do believe if we come up with a solution, we'll include it in the package, why not. Btw, you can use specifications and custom repositories side by side. They are not mutually exclusive. Refer to the sample app in this repo. We have CustomerRepository to demonstrate this. You keep the implementation in the infrastructure project, and the interface in the core project. |
Thanks a lot. |
If we can figure out how, we will support it for sure. |
Ok, this issue bothers me for some time, so I gave it another try. I finally figured out how to do it. We'll store information for each Include expression. Then, during the evaluation, we'll utilize this info to call public class IncludeExpressionInfo
{
public Expression ExpressionBody { get; set; }
public ReadOnlyCollection<ParameterExpression> ExpressionParameters { get; set; }
public Type EntityType { get; set; }
public Type PropertyType { get; set; }
public Type PreviousPropertyType { get; set; }
} I tested it, it works fine. Should do some further testing, and probably next week will post PR for this. |
Implemented in |
I want to use a where clause on when using Include as below:
Query.Where(r => r.Id == resourceId).Include(r => r.Banks.Where(b => b.Id == bankId))
but it doesn't filter out the result and fetches all banks related to specified resource (Where(r => r.Id == resourceId))
which is awful!
The text was updated successfully, but these errors were encountered: