-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
Eager loading include with using UseLazyLoadingProxies #15170
Comments
Sounds like this bug may be related to and is addressed in 3.0? Old behaviorBefore EF Core 3.0, once a DbContext was disposed there was no way of knowing if a given navigation property on an entity obtained from that context was fully loaded or not. Proxies would instead assume that a reference navigation is loaded if it has a non-null value, and that a collection navigation is loaded if it isn't empty. In these cases, attempting to lazy-load would be a no-op. New behaviorStarting with EF Core 3.0, proxies keep track of whether or not a navigation property is loaded. This means attempting to access a navigation property that is loaded after the context has been disposed will always be a no-op, even when the loaded navigation is empty or null. Conversely, attempting to access a navigation property that isn't loaded will throw an exception if the context is disposed even if the navigation property is a non-empty collection. If this situation arises, it means the application code is attempting to use lazy-loading at an invalid time, and the application should be changed to not do this. WhyThis change was made to make the behavior consistent and correct when attempting to lazy-load on a disposed DbContext instance. This seems to be exactly what I am attempting to do. |
@Bitz My first impression was that this is the issue that resulted in the breaking change you mention. However, that doesn't jive with, " |
Hey @ajcvickers I feel like I am misunderstanding how Here is proof that what I am saying happens: (API keys are random guids, nothing sensitive is being shown) |
@Bitz I was able to reproduce most of the behavior you are seeing and it does seem to be a duplicate of #12780. However, this: public class User
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string Name { get; set; }
public DateTime? LastUsed { get; set; }
public virtual Setting Settings { get; set; }
}
public class Setting
{
public int Id { get; set; }
}
public class BloggingContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseLazyLoadingProxies()
.UseSqlite("DataSource=testdb");
}
public DbSet<User> Users { get; set; }
}
public class Program
{
public static void Main()
{
using (var context = new BloggingContext())
{
context.Database.EnsureDeleted();
context.Database.EnsureCreated();
context.Add(new User {Settings = new Setting()});
context.SaveChanges();
}
User user;
using (var context = new BloggingContext())
{
var uid = 1;
user = context.Users.FirstOrDefault(x => x.UserId == uid);
//user = context.Users.Include(x => x.Settings).FirstOrDefault(x => x.UserId == uid);
}
var _ = user.Settings;
}
} |
I think it can be closed as a dupe since the main issue is solved in 3RC4, if I do encounter the FirstOrDefault issue, I will create another ticket referencing this one. Thanks! |
I am creating the db connection like so:
And I am trying to access an object like so:
The user object is as follows:
but upon accessing
Users.Settings
, it throws the error listed below.I understand what this means but it goes against my understanding of includes and how it causes eager loading.
My understanding was that when using an include and accessing the object explicitly by calling FirstOrDefault eager load the related objects to be populated immediately without the need for the db connection to remain open; but apparently, this is not the case. Am I missing something here about the usage or is this a bug?
Further information
db.Users.FirstOrDefault(x => x.UserId == uid);
works fine.db.Users.Include(x => x.Settings).FirstOrDefault(x => x.UserId == uid);
while not invokingUseLazyLoadingProxies()
works fine.I posted a question on SO assuming I was misusing it, but a user there directed me here informing me that it may be a bug. (https://stackoverflow.com/questions/55369146)
Steps to reproduce
Create object and connector as shown, try to include a related object and load data.
Upon accessing the include like so:
The error will be thrown.
Further technical details
EF Core version: 2.2.3
Database Provider: Microsoft.EntityFrameworkCore.Sqlite
Operating system: W10
IDE: Visual Studio 2017 15.9.9
The text was updated successfully, but these errors were encountered: