-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
Odata $filter and $orderby not working with Select to new DTO for one to one relationship #23877
Comments
full repro without odata: [ConditionalFact]
public virtual void Repro23877()
{
using var ctx = new MyContext();
ctx.Database.EnsureDeleted();
ctx.Database.EnsureCreated();
var baseQuery = ctx.Addresses.Select(x => new AddressDto
{
Id = x.Id,
ZipCode = x.ZipCode,
State = x.StateId != null ? new IdAndName { Value = x.StateId.Value, Text = x.State.Name } : null
});
var guid = Guid.NewGuid();
var query = baseQuery.Where(x => x.State.Value != guid).ToList();
}
public class AddressDto
{
public Guid Id { get; set; }
public string ZipCode { get; set; }
public IdAndName State { get; set; }
}
public class IdAndName
{
public Guid Value { get; set; }
public string Text { get; set; }
}
public class AddressEntity
{
public Guid Id { get; set; }
public string ZipCode { get; set; }
public Guid? StateId { get; set; }
public State State { get; set; }
}
public class State
{
public Guid Id { get; set; }
public string Name { get; set; }
}
public class MyContext : DbContext
{
public DbSet<AddressEntity> Addresses { get; set; }
public DbSet<State> States { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Repro23877;Trusted_Connection=True;MultipleActiveResultSets=true");
}
} |
in comparison, when we compare x.State.Value (or rather, |
|
@cap7ainjack you can workaround the issue by making Value of the query.Select(x =>
new AddressDto()
{
Id = x.Id,
ZipCode = x.ZipCode,
State = x.State != null ? new IdAndName() { Text = x.State.Name, Value= x.StateId.Value } : null,
}); |
That fixes is it. Thanks. I didnt get the Guid exception until now. I mean the previous error
is kind of replaced with Guid and nullable Guid comparison error. However, thanks again. This solves the issue. |
there is still a bug here, reopening the issue so that we can track & fix it. |
… new DTO for one to one relationship Problem was that during query optimization, TryOptimizeMemberAccessOverConditional could change the type of the expression (from non nullable to nullable), which then would throw when trying to re-construct the expression tree upstream. Fix is to change the type to the original as part of TryOptimizeMemberAccessOverConditional. Fixes #23877
… new DTO for one to one relationship Problem was that during query optimization, TryOptimizeMemberAccessOverConditional could change the type of the expression (from non nullable to nullable), which then would throw when trying to re-construct the expression tree upstream. Fix is to change the type to the original as part of TryOptimizeMemberAccessOverConditional. Fixes #23877
… new DTO for one to one relationship Problem was that during query optimization, TryOptimizeMemberAccessOverConditional could change the type of the expression (from non nullable to nullable), which then would throw when trying to re-construct the expression tree upstream. Fix is to change the type to the original as part of TryOptimizeMemberAccessOverConditional. Fixes #23877
Glad to see that this is being fixed. Could the fix be considered for cherry picking into a servicing release? |
… new DTO for one to one relationship Problem was that during query optimization, TryOptimizeMemberAccessOverConditional could change the type of the expression (from non nullable to nullable), which then would throw when trying to re-construct the expression tree upstream. Fix is to compensate for type changes across the visitor and only reconstructing original type at the top level (projection, lambda, method call arguments). Fixes #23877
… new DTO for one to one relationship Problem was that during query optimization, TryOptimizeMemberAccessOverConditional could change the type of the expression (from non nullable to nullable), which then would throw when trying to re-construct the expression tree upstream. Fix is to compensate for type changes across the visitor and only reconstructing original type at the top level (projection, lambda, method call arguments, etc). Fixes #23877
… new DTO for one to one relationship Problem was that during query optimization, TryOptimizeMemberAccessOverConditional could change the type of the expression (from non nullable to nullable), which then would throw when trying to re-construct the expression tree upstream. Fix is to compensate for type changes across the visitor and only reconstructing original type at the top level (projection, lambda, method call arguments, etc). Fixes #23877
@Erythnul sorry for the late response - the bugfix is quite risky, as it involves modifying type of the expression tree and has potential to break existing queries if we missed a case. Also, there is a relatively straightforward workaround - adding conversion to nullable. So sadly this fix won't be ported into the patch release. |
Since I update to .NET Core $orderby and $filter does not work in this specific case, which was perfectly working before.
The DTO models
// The SELECT:
And the request
Which was wokring perfectly in the .NET Framework now thorws and error:
The problem is obvious. Somehow Odata sends all the null check expression in the query...
I`m not using AutoMapper, I do all converts like this with select. And with the nested collection properties everything is fine.... but with the single ones which should be easies it is NOT...
When I change the null check to be like this:
I get another error:
"The operands for operator 'Equal' do not match the parameters of method 'op_Equality'."
I do not think there is other way to perform null check...
The text was updated successfully, but these errors were encountered: