-
Notifications
You must be signed in to change notification settings - Fork 30
issue #71 #104
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
base: master
Are you sure you want to change the base?
issue #71 #104
Conversation
P9avel
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please to merge
|
Please to merge this PR |
|
@koenbeuk Please merge this PR |
koenbeuk
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this PR, Apart from some minor changes, I did propose a workaround for the added unit test. functionality that would work today. Can you let me know in what scenarios my proposed workaround would not support and why we would need this PR merged?
Thanks again!
| { | ||
| public ProjectableAttribute() { } | ||
|
|
||
| public ProjectableAttribute(string useMemberBody, object memberBodyParameterValue) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A constructor would be an aggressive change as this would limit our ability in the future to add additional constructor arguments. Just having a property would be sufficient. Can this constructor be dropped?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment accepted
| /// <summary> | ||
| /// Parameters values for UseMemberBody. | ||
| /// </summary> | ||
| public object[]? MemberBodyParameterValues { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer the name UseMemberBodyArguments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment accepted
| if (reflectedExpression.Parameters.Count > 1) | ||
| { | ||
| var projectableAttribute = nodeMember.GetCustomAttribute<ProjectableAttribute>(false)!; | ||
| foreach (var prm in reflectedExpression.Parameters.Skip(1).Select((Parameter, Index) => new { Parameter, Index })) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer calling this parameterWithIndex to stay in sync with the naming conventions used throughout the rest of the code base
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment accepted
| var projectableAttribute = projectableMemberInfo.GetCustomAttribute<ProjectableAttribute>() | ||
| ?? throw new InvalidOperationException("Expected member to have a Projectable attribute. None found"); | ||
|
|
||
| var expression = GetExpressionFromGeneratedType(projectableMemberInfo); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should be no need to call this if projectableAttribute.UseMemberBody is not null
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment accepted
|
|
||
| if (expression is null && projectableAttribute.UseMemberBody is not null && projectableAttribute.MemberBodyParameterValues is null) | ||
| { | ||
| expression = GetExpressionFromGeneratedType(projectableMemberInfo, true, projectableAttribute.UseMemberBody); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The result will be overwritten by the call on line 24
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think differently that when calling line 20 the expression will not be empty
| public int Id { get; set; } | ||
| public List<OrderItem> OrderItem { get; set; } = new List<OrderItem>(); | ||
|
|
||
| [Projectable(nameof(GetOrderItemNameExpression), 1)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This example confuses me, could you not just have done:
[Projectable(UseMemberBody = nameof(GetOrderItemNameInnerExpressionWithArgument))]
public string FirstOrderPropName => GetOrderItemName(1);
private static Expression<Func<Order, string>> GetOrderItemNameInnerExpressionWithArgument()
=> new MyParameterExpressionVisitor(parameter: "id", value: 1).Visit(GetOrderItemNameInnerExpression());
private static Expression<Func<Order, int, string>> GetOrderItemNameInnerExpression()
=> (@this, id) => @this.OrderItem
.Where(av => av.Id == id)
.Select(av => av.Name)
.FirstOrDefault() ?? string.Empty;Where MyParameterExpressionVisitor swaps out the parameter named id for a constant value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm also confused, but we generate this call in runtime and therefore it is convenient for us to pass the value of the parameters through the attribute.
|
Hi, @koenbeuk When you planning to merge this PR? |
This request contains a solution to problem #71 and a test case of use. The request was prepared with the support of P9avel.