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

TemporalAll fails with JSON columns #30478

Closed
pekspro opened this issue Mar 14, 2023 · 2 comments · Fixed by #32006
Closed

TemporalAll fails with JSON columns #30478

pekspro opened this issue Mar 14, 2023 · 2 comments · Fixed by #32006
Assignees
Labels
area-json area-query closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported type-bug
Milestone

Comments

@pekspro
Copy link

pekspro commented Mar 14, 2023

If you have a JSON column in a temporal table and calls TemporalAll(), an System.InvalidOperationException is thrown with the message:

 Temporal query is trying to use navigation to an entity 'BlogDetails' which itself 
 doesn't map to temporal table. Either map the entity to temporal table or use 
 join manually to access it.

This is very similar to #29156.

Full sample

using Microsoft.EntityFrameworkCore;

using (var db = new BloggingContext())
{
    await db.Database.EnsureDeletedAsync();
    await db.Database.EnsureCreatedAsync();

    var blog = new Blog { Url = "http://example.com", Details = new BlogDetails() { Title = "Title" } };
    db.Add(blog);
    db.SaveChanges();

    var blogs = db.Blogs.ToList();

    // This thwrows: System.InvalidOperationException:
    // Temporal query is trying to use navigation to an entity 'BlogDetails' which itself doesn't map to
    // temporal table. Either map the entity to temporal table or use join manually to access it.
    var blogsHistory = db.Blogs.TemporalAll().ToList();
}

public class BloggingContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder
            .UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=ABlogDatabase;Trusted_Connection=True;")
            .LogTo(Console.WriteLine, new[] { DbLoggerCategory.Database.Command.Name, DbLoggerCategory.Database.Transaction.Name })
            ;
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder
            .Entity<Blog>(entity =>
            {
                entity.ToTable("Blog", b => b.IsTemporal());

                entity.OwnsOne(e => e.Details, ownedNavigationBuilder =>
                {
                    ownedNavigationBuilder.ToJson();
                });
            });
    }
}

public class Blog
{
    public int BlogId { get; set; }
    public required string Url { get; set; }
    public BlogDetails Details { get; set; } = null!;
}

public class BlogDetails
{
    public string Title { get; set; } = null!;
}

Include provider and version information

EF Core version: 7.0.4
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET 7.0
Operating system: Windows 11
IDE: Visual Studio 2022 17.5

@maumar maumar self-assigned this Mar 16, 2023
@maumar
Copy link
Contributor

maumar commented Mar 17, 2023

We have some validation making sure that the navigations coming from the entity mapped to temporal table can be expanded. However, we should circumvent all those checks for JSON entities, since those are always mapped to the same table as the owner (so they are always in sync) - we should also allow operations other than AsOf if all navigations are JSON based.

@iivmok
Copy link

iivmok commented Mar 28, 2023

Temporary workaround:

const string sqlServerIsTemporalAnnotation = "SqlServer:IsTemporal";
var entityType = (RuntimeEntityType)context.Model.FindRuntimeEntityType(typeof(YourJsonFieldType))!;

entityType.SetAnnotation(sqlServerIsTemporalAnnotation, true);

var data = await context.[Your query here];

entityType.RemoveAnnotation(sqlServerIsTemporalAnnotation);

maumar added a commit that referenced this issue Oct 10, 2023
We had a validation step preventing non AsOf temporal queries when we use navigation properties, as well as checking that all entities in the navigation chain are set as temporal. This should not apply to JSON entities,
since those always part of the entity.

Fix is to no longer perform the check for navigations mapped to JSON.

Fixes #30478
@maumar maumar modified the milestones: Backlog, 8.0.0 Oct 10, 2023
maumar added a commit that referenced this issue Oct 10, 2023
We had a validation step preventing non AsOf temporal queries when we use navigation properties, as well as checking that all entities in the navigation chain are set as temporal. This should not apply to JSON entities,
since those always part of the entity.

Fix is to no longer perform the check for navigations mapped to JSON.

Fixes #30478
maumar added a commit that referenced this issue Oct 10, 2023
We had a validation step preventing non AsOf temporal queries when we use navigation properties, as well as checking that all entities in the navigation chain are set as temporal. This should not apply to JSON entities,
since those always part of the entity.

Fix is to no longer perform the check for navigations mapped to JSON.

Fixes #30478
@maumar maumar added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Oct 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-json area-query closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported type-bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants