I'm using Entity Framework 4.1 code first approach.
I want to make eager loading as my the dafault configuration, and by that avoid using the Include extension method in each fetching query.
I did as recomended in MSDN, changing the simple lazy property at the DbContext constructor:
public class EMarketContext : DbContext
{
public EMarketContext()
{
// Change the default lazy loading to eager loading
this.Configuration.LazyLoadingEnabled = false;
}
}
unfortunately, this approach is not working. I have to use the Include method to perform eager loading in each query. Any ideas why?
Thanks in advance.
There is no default configuration for eager loading. You must always define Include or create some reusable method which will wrap adding include. For example you can place similar method to your context:
public IQueryable<MyEntity> GetMyEntities()
{
return this.MyEntities.Include(e => e.SomeOtherEntities);
}
Related
I'm trying to use Laravel Eager Loading in my project and I have read the documentation about it. Every example in documentation is about getting all instances of a model with Eager Loading. But is it just about getting all instance not just a single model?
Consider this :
public function single(Coin $coin)
{
$coin = $coin->with('exchanges')->get();
return view('public.coin',compact('coin'));
}
It is a controller method which loads a single Coin using route binding and injects the instance and I'm trying to eager load relations of that coin. but when I access $coin in my blade view file I get a list of all coins. So I can't eager load an injected model instance?!
You are looking for Lazy Eager Loading.
You can achieve what you want using:
public function single(Coin $coin)
{
$coin->load('exchanges');
return view('public.coin',compact('coin'));
}
Also, you can eager load relations when retrieving a single model like:
Coin::with('exchanges')->find($id);
I stumbled upon unexpected behaviour when using Entity Framework with PostgreSql.
When I query context with navigation property inside where clause, its always null and fails. But If I add there Include method pointing to navigational propery it's working
this will work
context.Garages.Include("PostalCode").Where(f=>f.PostalCode.RegionId == regionId)
this will not (PostalCode is null and fails on NullReference)
context.Garages.Where(f=>f.PostalCode.RegionId == regionId)
I don't think I had to add this to query when using MSSQL. Can anybdoy explain this to me.
If you want that your navigation properties be lazy loaded, then you need to declare them as virtual:
public Garage
{
//...
public virtual PostalCode PostalCode {get;set;}
}
In this link you will find the conditions that must follow your entities if you want to enable lazy loading for your entities and to have the Entity Framework track changes in your classes as the changes occur.
If that navigation property is already virtual, the other option that I think could cause that behavior is if you turn off Lazy Loading on your context:
public class YourContext : DbContext
{
public YourContext()
{
this.Configuration.LazyLoadingEnabled = false;
}
}
If you call the Include method, you are going to load the related entity as part of the query. This load behavior is called Eager Loading. On the other hand, if you use Lazy Loading, the related entity is going to be loaded the first time that is accessed, that is the behavior that you looking for.
New to EF. Following along with DBContext by Lerman/Miller.
When I start a new project, adding EF6 (Database First), the DBContext seems to be added as a default (ie I don't have to add the DBContext separately with T4). Also, for Lazy Loading, the "virtual" needed in the class definitions also seems to be there by default (I don't have to add it like in the book). Is this what is expected?
When you use Database First approach and use EF x DbContext Generator it creates the DbContext for you automatically and set the navigation properties, virtual. If you want to disable lazy loading you can simply use following code
public class MyContext : DbContext
{
public MyContext()
{
this.Configuration.LazyLoadingEnabled = false;
}
}
Most probably the books you are reading are for code first development. If you use database first(especially with the designer) you don't need to make changes.
I need to customize the insert/update methods for an entity on a CRUD application using ASP.NET Dymanic Data and Entity Framework. I found a solution for an application using Linq To SQL on http://extremedev.blogspot.com.es/2011/03/custom-insertupdate-on-linqtosql-and.html .
The customization is for add some business logic.
I didn't find any method to overload on EF or something similar, any suggestion? Is it possible without using triggers or modifing the methods ItemInserted or ItemUpdated on the forms in template pages?
Thx
The method you referenced above is good, another I have seen is this one:
You can override the SubmitChanges method of your data context and check the set of changes and trap each object and each change type (insert, update, delete)
public override void SubmitChanges(System.Data.Linq.ConflictMode failureMode)
{
ChangeSet changeset = GetChangeSet();
foreach (var f in changeset.Inserts.OfType<Foo>())
{
DoSomethingSpecial(f);
}
private void DoSomethingSpecial(Foo instance)
{
... // do something with another datacontext instance
}
}
Try the next link. I think this is what you need
http://csharpbits.notaclue.net/2008/05/dynamicdata-automatic-column-update.html
So I'm using Entity Framework Code First (so no .edmx)
I have a base entity class with a bool IsEnabled to do soft delete's
I am using repository pattern so all queries against the repository can be filtered out with IsEnabled.
However any time I use the repository to get an MyType which is IsEnabled, Lazy Loading MyType.Items may mean that Items could be not enabled.
Is there a way, perhaps with EF Fluent to describe how to do filtering on tables?
Update:
If I have a Dbset
public class UnitOfWork : DbContext
{
private IDbSet<MyObj> _MyObj;
public IDbSet<MyObj> MyObjs
{
get { return _MyObj ?? (_MyObj = base.Set<MyObj>()); }
}
}
Is there any way I can tell the DbContext to filter the DbSet?
No, there is no way to define a filter for lazy loading (also not for eager loading using Include). If you want that your navigation collections only get populated with items where IsEnabled is true you can only shape your queries accordingly, for example with explicit loading:
context.Entry(parent).Collection(p => p.Items).Query()
.Where(i => i.IsEnabled)
.Load();
This will populate the Items collection of parent only with the enabled items.
Edit
I feel a bit like the messenger of the bad news about a lost battle who gets his head knocked off. Maybe it's too hard to believe that Entity Framework sometimes does not have the capabilities you want. To improve my chance to convince you I add a quote from an authority, Julie Lerman:
Neither eager loading nor deferred/lazy loading in the Entity
Framework allows you to filter or sort the related data being
returned.
It looks like it is still possible. If you are intrested you can take a look at the Wiktor Zychla blogpost, where he gives a solution to the soft delete problem.
This http://blogs.claritycon.com/blog/2012/01/25/a-smarter-infrastructure-automatically-filtering-an-ef-4-1-dbset/ basically defines how I can achieve what I was looking for.
Basically you create a FilteredDbSet and make all your DbContext IDbSet's return it.