Explicitly Loading filtered navigation property via Load() not working

I have a query that I want to return an entity with a filtered collection navigation property. According to the EF6 document I should be able to load it via Read more. However, after the context is disposed, I'll get the following error when trying to access the navigation property outside.
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
I think the problem is that property is not loaded, because if I manually use a debugger to look at the navigation property before the context is disposed it will trigger the lazy loading, and ProductVariants
will be loaded correctly without an error.
I understand that I can just do two queries and return separately or just use include()
to include the whole List of ProductVariance
tied to that product. However, I wonder why Load()
doesn't work?
Here is my simplified code:
void RouteToVariant() {
Product product = productDAO.FindByProductKeyWithVariantsByCustomer(productKey, variantType);
// exception thrown here
int ProductVariantID = product.ProductVariants.ProductVariantID;
}
// The method in the DAO class
public Product FindByProductKeyWithVariantsByCustomer (int productKey, string variantType) {
using (var context = new MyDbContext())
{
var product = context.Products
.Find(productKey);
/* Also tried .ToList() instead of .Load()
and assign the list to product.ProductVariants but didn't work */
context.Entry(product)
.Collection(p => p.ProductVariants)
.Query()
.Where(pv => pv.VariantType == variantType)
.Load();
return product;
}
}
And the entities:
public class Product {
[Key]
public int ProductKey {get;set;}
public virtual ICollection<ProductVariant> ProductVariants {get;set;}
}
public class ProductVariant {
[Key]
public int ProductVariantID {get;set;}
public int ProductKey {get;set;}
public Product Product {get;set;}
public string VariantType {get;set;}
}
// and the fluent API in another class for configuring the relation
public ProductVariantConfiguration()
{
HasRequired(m => m.Product)
.WithMany(o => o.ProductVariants)
.HasForeignKey(m => m.ProductKey);
}
Answer
I figured it is because we need to disable lazy loading for query()
.
The collection is loaded normally after I've added the line that disables lazy loading.
According to the document:
When using the Query method it is usually best to turn off lazy loading for the navigation property. This is because otherwise the entire collection may get loaded automatically by the lazy loading mechanism either before or after the filtered query has been executed.
Although I don't see how this is related to the collection not being loaded at all...
public Product FindByProductKeyWithVariantsByCustomer (int productKey, string variantType) {
using (var context = new MyDbContext())
{
// disables lazy loading
context.Configuration.LazyLoadingEnabled = false;
var product = context.Products
.Find(productKey);
context.Entry(product)
.Collection(p => p.ProductVariants)
.Query()
.Where(pv => pv.VariantType == variantType)
.Load();
return product;
}
}
Enjoyed this article?
Check out more content on our blog or follow us on social media.
Browse more articles