-
-
Notifications
You must be signed in to change notification settings - Fork 155
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
Allow creating an Expression<Func<>> instead of a IQueryable Projection #733
Comments
I understand your use case and I think this could probably be helpful in other scenarios. However, as I think this is an edge case, it is not a priority for us. But I would be happy to accept a PR that implements this. |
|
nvm might be a bit trickier than I thought, sorry |
The Expression must already be created in order to use IQueryable<>, so I figured it might not be too difficult. If I find some free time this month I might dive into the code |
Yeah, I think the logic is identical to It's possible to add, but not the quick, 15 minute change I wanted 😆 |
I started experimenting on this. I stumbled on some assumptions that currently seem to be baked in, but so far nothing major; in fact with some hacks I managed to get it somewhat working: //HintName: Mapper.g.cs
// <auto-generated />
#nullable enable
public partial class Mapper
{
private partial global::System.Linq.IQueryable<global::B> Map(global::System.Linq.IQueryable<global::A> source)
{
return System.Linq.Queryable.Select(source, MapToExpression(42));
}
private global::System.Linq.Expressions.Expression<global::System.Func<global::A, global::B>> MapToExpression(int source)
{
#nullable disable
return x => new global::B()
{
Parent = x.Parent != null ? new global::B() : default,
};
#nullable enable
}
} I'll try experimenting some more, but I would like to know if this direction looks somewhat reasonable. I am aiming for something like: //HintName: Mapper.g.cs
// <auto-generated />
#nullable enable
public partial class Mapper
{
private partial global::System.Linq.IQueryable<global::B> Map(global::System.Linq.IQueryable<global::A> source)
{
return System.Linq.Queryable.Select(source, MapToExpression());
}
private global::System.Linq.Expressions.Expression<global::System.Func<global::A, global::B>> MapToExpression()
{
#nullable disable
return x => new global::B()
{
Parent = x.Parent != null ? new global::B() : default,
};
#nullable enable
}
} (aka no hacked source). Later on I would like to memoize the expression, but that might not be really relevant (it would be a minor optimization for the allocations, definitely optional). |
@ranma42 looks good so far 😊 Thank you for your efforts. [Mapper]
public partial class Mapper
{
public partial IQueryable<B> Map(this IQueryable<A> source);
} should generate [Mapper]
public partial class Mapper
{
public partial global::System.Linq.IQueryable<global::B> Map(this global::System.Linq.IQueryable<global::A> source)
{
#nullable disable
return System.Linq.Queryable.Select(source, x => ...);
#nullable enable
}
} but [Mapper]
public partial class Mapper
{
public partial Expression<Func<A, B>> Mapper();
} should generate [Mapper]
public partial class Mapper
{
public partial Expression<Func<A, B>> Mapper()
{
#nullable disable
return x => ...;
#nullable enable
}
} If both are declared, the queryable method could call the expression builder, but IMO this would be optional for a first version and could be an optimisation later on. |
It is possible to get a
IQueryable<B> ProjectToB(IQueryable<A> query)
which can be used asIs your feature request related to a problem? Please describe.
We have a generic class like follows:
Describe the solution you'd like
I would prefer being able to create an
Expression<Func<A, B>>
and give it to my base repository.This will make the query cleaner and easier to read.
Describe alternatives you've considered
The aforementioned code works, but I'd prefer the new variant.
Additional context
I'm happy to hear your opinions on this matter.
The text was updated successfully, but these errors were encountered: