Skip to content
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

Query: Cosmos: Generate enum literal/parameter correctly #20934

Merged
merged 1 commit into from
May 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/EFCore.Cosmos/Query/Internal/QuerySqlGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,8 @@ protected override Expression VisitSqlConstant(SqlConstantExpression sqlConstant

private JToken GenerateJToken(object value, CoreTypeMapping typeMapping)
{
value = ConvertUnderlyingEnumValueToEnum(value, typeMapping.ClrType);

var converter = typeMapping.Converter;
if (converter != null)
{
Expand All @@ -377,6 +379,15 @@ private JToken GenerateJToken(object value, CoreTypeMapping typeMapping)
return (value as JToken) ?? JToken.FromObject(value, CosmosClientWrapper.Serializer);
}

// Enum when compared to constant will always have value of integral type
// when enum would contain convert node. We remove the convert node but we also
// need to convert the integral value to enum value.
// This allows us to use converter on enum value or print enum value directly if supported by provider
private object ConvertUnderlyingEnumValueToEnum(object value, Type clrType)
=> value?.GetType().IsInteger() == true && clrType.UnwrapNullableType().IsEnum
? Enum.ToObject(clrType.UnwrapNullableType(), value)
: value;

/// <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
Expand Down
26 changes: 1 addition & 25 deletions test/EFCore.Cosmos.FunctionalTests/BuiltInDataTypesCosmosTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,30 +30,6 @@ public override Task Can_filter_projection_with_captured_enum_variable(bool asyn
return base.Can_filter_projection_with_captured_enum_variable(async);
}

[ConditionalFact(Skip = "Issue #16919")]
public override void Can_query_using_any_data_type()
{
base.Can_query_using_any_data_type();
}

[ConditionalFact(Skip = "Issue #16919")]
public override void Can_query_using_any_data_type_nullable_shadow()
{
base.Can_query_using_any_data_type_nullable_shadow();
}

[ConditionalFact(Skip = "Issue #16919")]
public override void Can_query_using_any_data_type_shadow()
{
base.Can_query_using_any_data_type_shadow();
}

[ConditionalFact(Skip = "Issue #16919")]
public override void Can_query_using_any_nullable_data_type()
{
base.Can_query_using_any_nullable_data_type();
}

[ConditionalFact(Skip = "Issue #16919")]
public override void Can_query_using_any_nullable_data_type_as_literal()
{
Expand All @@ -66,7 +42,7 @@ public override void Can_query_with_null_parameters_using_any_nullable_data_type
base.Can_query_with_null_parameters_using_any_nullable_data_type();
}

[ConditionalFact(Skip = "Issue #16919")]
[ConditionalFact(Skip = "Issue #16920")]
public override void Can_insert_and_read_back_with_string_key()
{
base.Can_insert_and_read_back_with_string_key();
Expand Down
26 changes: 1 addition & 25 deletions test/EFCore.Cosmos.FunctionalTests/CustomConvertersCosmosTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,30 +36,6 @@ public override Task Can_filter_projection_with_captured_enum_variable(bool asyn
return base.Can_filter_projection_with_captured_enum_variable(async);
}

[ConditionalFact(Skip = "Issue #16919")]
public override void Can_query_using_any_data_type()
{
base.Can_query_using_any_data_type();
}

[ConditionalFact(Skip = "Issue #16919")]
public override void Can_query_using_any_data_type_nullable_shadow()
{
base.Can_query_using_any_data_type_nullable_shadow();
}

[ConditionalFact(Skip = "Issue #16919")]
public override void Can_query_using_any_data_type_shadow()
{
base.Can_query_using_any_data_type_shadow();
}

[ConditionalFact(Skip = "Issue #16919")]
public override void Can_query_using_any_nullable_data_type()
{
base.Can_query_using_any_nullable_data_type();
}

[ConditionalFact(Skip = "Issue #16919")]
public override void Can_query_using_any_nullable_data_type_as_literal()
{
Expand All @@ -72,7 +48,7 @@ public override void Can_query_with_null_parameters_using_any_nullable_data_type
base.Can_query_with_null_parameters_using_any_nullable_data_type();
}

[ConditionalFact(Skip = "Issue #16919")]
[ConditionalFact(Skip = "Issue #16920")]
public override void Can_insert_and_read_back_with_string_key()
{
base.Can_insert_and_read_back_with_string_key();
Expand Down
25 changes: 25 additions & 0 deletions test/EFCore.Specification.Tests/BuiltInDataTypesTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1994,6 +1994,31 @@ public virtual void Can_read_back_bool_mapped_as_int_through_navigation()
Assert.True(result.BoolField);
}

[ConditionalFact]
public virtual void Can_compare_enum_to_constant()
{
using var context = CreateContext();
var query = context.Set<AnimalIdentification>()
.Where(a => a.Method == IdentificationMethod.EarTag)
.ToList();

var result = Assert.Single(query);
Assert.Equal(IdentificationMethod.EarTag, result.Method);
}

[ConditionalFact]
public virtual void Can_compare_enum_to_parameter()
{
var method = IdentificationMethod.EarTag;
using var context = CreateContext();
var query = context.Set<AnimalIdentification>()
.Where(a => a.Method == method)
.ToList();

var result = Assert.Single(query);
Assert.Equal(IdentificationMethod.EarTag, result.Method);
}

[ConditionalFact]
public virtual void Object_to_string_conversion()
{
Expand Down