-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Cosmos: Complex properties binding #37400
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: main
Are you sure you want to change the base?
Changes from 15 commits
601adaa
072889d
35ef5c7
221d5a7
8143650
b2d51dd
1a116bc
e5dcfe1
81428b1
0e45c86
cdf1861
b69203b
b66d913
699da56
900f117
004d37a
d221dbc
a8eeba9
3698238
1702ac9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -352,24 +352,67 @@ UnaryExpression unaryExpression | |
|
|
||
| Expression NullSafeUpdate(Expression? expression) | ||
| { | ||
| Expression updatedMemberExpression = memberExpression.Update( | ||
| expression != null ? MatchTypes(expression, memberExpression.Expression!.Type) : expression); | ||
| if (expression is null) | ||
| { | ||
| return memberExpression.Update(expression); | ||
| } | ||
|
|
||
| var expressionValue = Expression.Parameter(expression.Type); | ||
| var assignment = Expression.Assign(expressionValue, expression); | ||
|
|
||
| if (expression.Type.IsNullableType() == true | ||
JoasE marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| && !memberExpression.Type.IsNullableType() | ||
| && memberExpression.Expression is MemberExpression innerMember | ||
| && innerMember.Type.IsNullableValueType() == true | ||
| && memberExpression.Member.Name == nameof(Nullable<>.Value)) | ||
| { | ||
| var nullCheck = Expression.Not( | ||
| Expression.Property(expressionValue, nameof(Nullable<>.HasValue))); | ||
| var conditionalExpression = Expression.Condition( | ||
| nullCheck, | ||
| Expression.Default(memberExpression.Type), | ||
| Expression.Property(expressionValue, nameof(Nullable<>.Value))); | ||
|
|
||
| return Expression.Block( | ||
| [expressionValue], | ||
| assignment, | ||
| conditionalExpression); | ||
| } | ||
|
|
||
| Expression updatedMemberExpression = memberExpression.Update(MatchTypes(expressionValue, memberExpression.Expression!.Type)); | ||
|
|
||
| if (expression?.Type.IsNullableType() == true) | ||
| if (expression.Type.IsNullableType() == true) | ||
| { | ||
| var nullableReturnType = memberExpression.Type.MakeNullable(); | ||
| if (!memberExpression.Type.IsNullableType()) | ||
|
|
||
| if (!updatedMemberExpression.Type.IsNullableType()) | ||
| { | ||
| updatedMemberExpression = Expression.Convert(updatedMemberExpression, nullableReturnType); | ||
| } | ||
|
|
||
| Expression nullCheck; | ||
| if (expression.Type.IsNullableValueType()) | ||
| { | ||
| // For Nullable<T>, use HasValue property instead of equality comparison | ||
| // to avoid issues with value types that don't define the == operator | ||
| nullCheck = Expression.Not( | ||
| Expression.Property(expressionValue, nameof(Nullable<>.HasValue))); | ||
| } | ||
| else | ||
| { | ||
| nullCheck = Expression.Equal(expressionValue, Expression.Default(expression.Type)); | ||
| } | ||
|
|
||
| updatedMemberExpression = Expression.Condition( | ||
| Expression.Equal(expression, Expression.Default(expression.Type)), | ||
| Expression.Constant(null, nullableReturnType), | ||
| nullCheck, | ||
| Expression.Default(nullableReturnType), | ||
| updatedMemberExpression); | ||
| } | ||
|
|
||
| return updatedMemberExpression; | ||
| return Expression.Block( | ||
| [expressionValue], | ||
| assignment, | ||
| updatedMemberExpression); | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -639,8 +682,21 @@ UnaryExpression unaryExpression | |
| updatedMethodCallExpression = Expression.Convert(updatedMethodCallExpression, nullableReturnType); | ||
| } | ||
|
|
||
| Expression nullCheck; | ||
| if (@object.Type.IsNullableValueType()) | ||
| { | ||
| // For Nullable<T>, use HasValue property instead of equality comparison | ||
| // to avoid issues with value types that don't define the == operator | ||
| nullCheck = Expression.Not( | ||
| Expression.Property(@object, nameof(Nullable<>.HasValue))); | ||
| } | ||
| else | ||
| { | ||
| nullCheck = Expression.Equal(@object, Expression.Constant(null, @object.Type)); | ||
| } | ||
|
|
||
| return Expression.Condition( | ||
| Expression.Equal(@object, Expression.Default(@object.Type)), | ||
| nullCheck, | ||
| Expression.Constant(null, nullableReturnType), | ||
| updatedMethodCallExpression); | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|
|
||
| namespace Microsoft.EntityFrameworkCore.Query.Internal; | ||
|
|
||
| #pragma warning disable EF1001 // StructuralTypeMaterializerSource is pubternal | ||
|
|
||
| /// <summary> | ||
| /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to | ||
| /// the same compatibility standards as public APIs. It may be changed or removed without notice in | ||
| /// any release. You should only use it directly in your code with extreme caution and knowing that | ||
| /// doing so can result in application failures when updating to a new Entity Framework Core release. | ||
| /// </summary> | ||
| public class CosmosStructuralTypeMaterializerSource(StructuralTypeMaterializerSourceDependencies dependencies) | ||
| : StructuralTypeMaterializerSource(dependencies) | ||
| { | ||
| /// <summary> | ||
| /// Complex properties are not handled in the initial materialization expression, | ||
| /// So we can more easily generate the necessary nested materialization expressions later in CosmosShapedQueryCompilingExpressionVisitor. | ||
JoasE marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| /// </summary> | ||
| protected override bool ReadComplexTypeDirectly(IComplexType complexType) | ||
| => false; | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.