Skip to content

Commit

Permalink
Translate __jObject to Access Root
Browse files Browse the repository at this point in the history
Fixes #18710
  • Loading branch information
TheFanatr committed Aug 22, 2020
1 parent d9b7dea commit b72ade9
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ public virtual Expression BindProperty([NotNull] IProperty property, bool client
}

if (!clientEval
// TODO: Remove once __jObject is translated to the access root in a better fashion and
// would not otherwise be found to be non-translatable. See issues #17670 and #14121.
&& property.Name != EntityFrameworkCore.Metadata.Conventions.StoreKeyConvention.JObjectPropertyName
&& expression.Name.Length == 0)
{
// Non-persisted property can't be translated
Expand Down
6 changes: 5 additions & 1 deletion src/EFCore.Cosmos/Query/Internal/KeyAccessExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,11 @@ protected override void Print(ExpressionPrinter expressionPrinter)
/// 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 override string ToString() => $"{AccessExpression}[\"{Name}\"]";
public override string ToString() => Name?.Length > 0
? $"{AccessExpression}[\"{Name}\"]"
// TODO: Remove once __jObject is translated to the access root in a better fashion.
// See issue #17670 and related issue #14121.
: $"{AccessExpression}";

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Linq.Expressions;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Microsoft.EntityFrameworkCore.Utilities;
using Newtonsoft.Json.Linq;

Expand Down Expand Up @@ -33,7 +37,8 @@ public CosmosTypeMappingSource([NotNull] TypeMappingSourceDependencies dependenc
_clrTypeMappings
= new Dictionary<Type, CosmosTypeMapping>
{
{ typeof(byte[]), new CosmosTypeMapping(typeof(byte[]), keyComparer: new ArrayStructuralComparer<byte>()) }
{ typeof(byte[]), new CosmosTypeMapping(typeof(byte[]), keyComparer: new ArrayStructuralComparer<byte>()) },
{ typeof(JObject), new CosmosTypeMapping(typeof(JObject)) }
};
}

Expand Down
81 changes: 81 additions & 0 deletions test/EFCore.Cosmos.FunctionalTests/ReloadTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore.TestUtilities;
using Xunit;
using Newtonsoft.Json.Linq;

namespace Microsoft.EntityFrameworkCore.Cosmos
{
public class ReloadTest
{
public static IEnumerable<object[]> IsAsyncData = new[]
{
new object[] { true },
new object[] { false }
};

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public async Task Entity_reference_can_be_reloaded(bool async)
{
await using var testDatabase = CosmosTestStore.CreateInitialized("ReloadTest");

using var context = new ReloadTestContext(testDatabase);
await context.Database.EnsureCreatedAsync();

var entry = context.Add(new Item { Id = 1337 });

await context.SaveChangesAsync();

var itemJson = entry.Property<JObject>("__jObject").CurrentValue;
itemJson["unmapped"] = 2;

if (async)
{
await entry.ReloadAsync();
}
else
{
entry.Reload();
}

itemJson = entry.Property<JObject>("__jObject").CurrentValue;
Assert.Null(itemJson["unmapped"]);
}

public class ReloadTestContext : DbContext
{
private readonly string _connectionUri;
private readonly string _authToken;
private readonly string _name;

public ReloadTestContext(CosmosTestStore testStore)
{
_connectionUri = testStore.ConnectionUri;
_authToken = testStore.AuthToken;
_name = testStore.Name;
}

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseCosmos(
_connectionUri,
_authToken,
_name,
b => b.ApplyConfiguration());
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
}

public DbSet<Item> Items { get; set; }
}

public class Item
{
public int Id { get; set; }
}
}
}

0 comments on commit b72ade9

Please sign in to comment.