KEMBAR78
Support lazy and explicit loading from entities queried with NoTracking behavior · Issue #10042 · dotnet/efcore · GitHub
Skip to content

Support lazy and explicit loading from entities queried with NoTracking behavior #10042

@JoesGab

Description

@JoesGab

Explicit loading of a Reference does not populate the navigation property when QueryTrackingBehavior.NoTracking is set and AsTracking() is used as an override.

Explicit loading of a Collection does work as expected though.

Steps to reproduce

Minimalistic example for various combinations included. The issue arises only in the last assert statement of the second using block.

Program.cs

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Microsoft.EntityFrameworkCore;

namespace NoTrackingBug
{
    public class BloggingContext : DbContext
    {
        public DbSet<Blog> Blogs { get; set; }
        public DbSet<Post> Posts { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlite("Data Source=blogging.db");
        }
    }

    public class Blog
    {
        public int BlogId { get; set; }
        public string Url { get; set; }

        public List<Post> Posts { get; set; }

        public int OwnerId { get; set; }
        public Person Owner { get; set; }
    }

    public class Post
    {
        public int PostId { get; set; }
        public string Title { get; set; }

        public int BlogId { get; set; }
        public Blog Blog { get; set; }
    }

    public class Person
    {
        public int PersonId { get; set; }
        public string Name { get; set; }

        public List<Blog> OwnedBlogs { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // Setup the example
            using (var db = new BloggingContext())
            {
                if (!db.Blogs.Any())
                {
                    db.Blogs.Add(new Blog
                    {
                        Url = "http://blogs.msdn.com/adonet",
                        Posts = new List<Post>{
                            new Post { Title = "SomeTitle" }
                        },
                        Owner = new Person
                        {
                            Name = "Kobert"
                        }
                    });

                    db.SaveChanges();
                }
            }

            // Explicit load and .NoTracking => does not work for References
            using (var db = new BloggingContext())
            {
                db.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;

                var blog = db.Blogs
                    .AsTracking()
                    .Single();

                db.Entry(blog)
                    .Collection(b => b.Posts)
                    .Load();

                db.Entry(blog)
                    .Reference(b => b.Owner)
                    .Load();

                Debug.Assert(blog.Posts != null);
                Debug.Assert(blog.Owner != null); // <== This will fail!
            }

            // Eager load and .NoTracking => does work
            using (var db = new BloggingContext())
            {
                db.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;

                var blog = db.Blogs
                    .Include(b => b.Posts)
                    .Include(b => b.Owner)
                    .AsTracking()
                    .Single();

                Debug.Assert (blog.Posts != null);
                Debug.Assert (blog.Owner != null);
            }
            
            // Explicit load and .TrackAll => does work
            using (var db = new BloggingContext())
            {
                var blog = db.Blogs
                    .Single();

                db.Entry(blog)
                    .Collection(b => b.Posts)
                    .Load();

                db.Entry(blog)
                    .Reference(b => b.Owner)
                    .Load();

                Debug.Assert(blog.Posts != null);
                Debug.Assert(blog.Owner != null);
            }
        }
    }
}

Further technical details

EF Core version: 1.1.0 and 2.0.0
Database Provider: Microsoft.EntityFrameworkCore.SqlServer and Micrisoft.EntityFrameworkCore.Sqlite
Operating system: Windows 7 Enterprise
IDE: Visual Studio 2017 Enterprise and Visual Studio Code

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions