darxis / entityframework.lazyloading Goto Github PK
View Code? Open in Web Editor NEWLazyLoading for EF Core
License: MIT License
LazyLoading for EF Core
License: MIT License
I took a quick stab at trying to upgrade it but I got stuck at an error in LazyLoadingEntityMaterializerSource. The first time was instantiated currentDbContext was null, but after that it was fine.
According to the EF roadmap they do have a stretch goal of lazy loading in their 2.1 release timed with the release of .NET Core 2.1.
UPDATE: After more digging, the extra calls are actually being caused by change tracking (on load!), which is causing the lazy loading to look up data when tracking asks for it. This is still causing problems but means what I was wondering about earlier isn't relevant.
New question: is this happening in other peoples' uses of this or is there a way around it?
Original below:
I'm trying to use this with my EF Core project but based on the logs, it seems to be eager loading everything.
Can you confirm this still works?
I'm not using a DBContextFactory
pattern in the way your example is, and I'm confused by the seemingly unused _isLazy
variable in your example code. Could either of these things be a factor?
Thanks
Hi, Consider the following case:
using (var dbContext = lazyFactory.Create(factoryOptions))
{
try
{
var instructorAbercrombie = dbContext.Set<Instructor>().First(x => x.LastName == "Abercrombie");
var coursesOfinstructorAbercrombie = instructorAbercrombie.CourseAssignments.Select(x => x.Course);
var courseCount = coursesOfinstructorAbercrombie.Count();
Console.WriteLine($"Instructor Abercrombie has {courseCount} courses.");
}
catch (ObjectDisposedException)
{
Console.WriteLine($"{nameof(ObjectDisposedException)} occured (ConcurrencyDetector).");
}
}
you can reproduce the exception based on this.
In the current version, for each Reference you need to define in your model a field of type LazyReference.
Ex:
public class Course
{
...
private LazyReference<Department> _departmentLazy = new LazyReference<Department>();
public Department Department
{
get
{
return _departmentLazy.GetValue(this, nameof(Department));
}
set
{
_departmentLazy.SetValue(value);
}
}
...
}
Using dynamic Proxy objects would be better, because you don't have to define in your model such fields.
Hi, could you please provide sample usage for LazyCollection? Tried to change type of a property from ICollection<> to LazyCollection<> and accessing says that "The type of navigation property 'UserGroupRoles' on the entity type 'Role' is 'LazyCollection' for which it was not possible to create a concrete instance. Either initialize the property before use, add a public parameterless constructor to the type, or use a type which can be assigned a HashSet<> or List<>.'" so obviously this is not the good direction. Thanks
PerDbContextCompiledQueryCache makes compiled queries per context, obviously as its name suggests. As @darxis pointed out earlier, ICompiledQueryCache by default is registered as a singleton in EF Core (see _coreServices Dictionary), now it is overridden to be Scoped by LazyLoadingOptionsExtension. In many scenarios, DbContexts are living for just a short time interval, therefore we lose compiled query caching by opening another one, however asking just the same query many times possibly. I haven't ran load tests against this scenario, but won't this affect performance?
Connected issue: in current EF core dev branch CompiledQueryCache accepts only an IMemoryCache parameter in its constructor therefore from the next version, LL won't be able to get the ICurrentDbContext from IDbContextServices parameter anymore (see current CompiledQueryCache.cs).
Under certain circumstances, a LazyReference could be loaded infinite times caused by cyclic references.
LazyLoadingEntityMaterializerSource
by default (by EntityFramework) is registered as Singleton. LazyLoadingEntityMaterializerSource
is DbContext-scoped so it can't be a Singleton.
Create and use two LazyLoading-enabled DbContexts at the same time. Entity references/collections from both DbContexts will get queried within the second DbContext.
Building and running unit tests with Travis-CI
We can simplify API of LazyReference<T>
by using [CallerMemberName]
attribute:
public sealed class LazyReference<T>
{
public T GetValue(object parent, [CallerMemberName] string referenceName = null);
}
And we can write
private LazyReference<Parent> _parentLazy = new LazyReference<Parent>();
public Parent Parent
{
get => _parentLazy.GetValue(this);
set => _parentLazy.SetValue(value);
}
instead of
get => _parentLazy.GetValue(this, nameof(Parent));
LazyCollection.EnsureLoaded
method behavior is invalid.
When an exception is thrown inside this method, the _loading
flag will not get reset.
The _loading
flag should be cleared on method exit.
Same for LazyReference
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.