I am using EF4, and I using the System.Data.Entity dll in my class. However, I can't see the load method of my navigation property of my entity.
How can I access to this method?
What I am doing is create e 4.0 project of .NET, create my edmx from a database, right click in the model edmx and I generate a DBContext.
However, I can access to the local property of my context, that I think that is a feature of EF4.
Thanks.
Daimroc.
For the DbContext approach, the IsLoaded property and Load method have been moved:
context.Entry(yourEntity)
.Collection(entity => entity.NavigationProperty)
.IsLoaded;
context.Entry(yourEntity)
.Collection(entity => entity.NavigationProperty)
.Load();
Entry method: http://msdn.microsoft.com/en-us/library/gg696578(v=vs.103).aspx
Collection method: http://msdn.microsoft.com/en-us/library/gg671324(v=vs.103).aspx
IsLoaded property: http://msdn.microsoft.com/en-us/library/gg696146(v=vs.103).aspx
Load method: http://msdn.microsoft.com/en-us/library/gg696220(v=vs.103).aspx
When you write the query (all this also works with lambda syntax as well btw)
From a in context.EntitySet.Include("Navigation Property NAme")
select a
and all will be there ;) .. or more to the point the navigation properties will be populated.
can be wierd with lots of joins though
you can also
From a in context.EntitySet.Include("Navigation1.Navigation2.Navigation2")
.Include("SomeOtherNavigation")
select a
where navigation1 and SomeOtherNavigation are navigation properties on the entity set
Failing that you can turn on lazy loading in the context. But its evil imo.
Also it doesnt really scale well when you go for an SOA approach as you need to include prior to knowing about the lazy load in your repository.
Ie you run the query in your repository, send stuff over the service and then want the navigation properties in the front end ... by which time its too late to lazy load ... EG you are using a wcf service that doesn't use data services.
Important to note that you ahve to use Include on the EntitySet, it is not on an IQueryable<>.
A real example:
var csg = from ucsg in c.UserCarShareGroups.Include("UserCarShareGroups.User.UserVehicles")
where ucsg.User.UserName.ToLower() == userName.ToLower()
&& ucsg.CarShareGroup.Carpark.Name.ToLower().Equals(carparkName.ToLower())
&& ucsg.DeletedBy == null
select ucsg.CarShareGroup;
(the database has case sensitive collation for some reason)
An alternate approach (and maybe more relevant is here)
Entity Framework - Trouble with .Load()
However I like doing it the way I said because it is explicit and I know exactly what is being pulled out. Especially when dealing with large datasets.
An answer to a question that combines my concerns with Load() is here:
Entity Framework 4 load and include combine
Related
I am adding new entity to the context and I would like populate all its references collections once the add is done. Issue is, I am reading the same entity from the context which I created during the add(), basically EF doesn't go to the DB. This is correct behaviour, but how do I get around it ?
Repo().Add(newEntity);
Repo().Reload(newEntity);
This reloads the entity from DB however I am not getting the references (FK relations). I have found how to load the reference, however I would need a generic way how to load all the references for any entity.
var entry = Context.Entry(entity);
entry.Reference("ReferenceName").Load();
Is the above the correct approach or is there some other way ?
Without seeing your repository code, I am guessing it's a lazy loading issue.
This site explains eager vs lazy loading: http://msdn.microsoft.com/en-us/data/jj574232.aspx
You can either specify exactly what references you want to bring back by using the .Include() in your repo (good for long chains where you dont need everything).
context.Set<whateverType>.Include(t => t.(whatever you are referencing)).Where(t => t.id = id);
Or you can specify the context to use eager loading and bring back everything with your retrieval.
context.LazyLoadingEnabled = false;
I've got a couple of entities in a parent-child relationship: Family (parent) and Updates (child). I want to read a list of families without the corresponding updates. There are only 17 families but about 60,000 updates so I really don't want the updates.
I used EntitiesToDTOs to generate a DTO from the Family entity and to create an assembler for converting the Family entity to the FamilyDTO. The ToDTO method of the assembler looks like:
public static FamilyDTO ToDTO(this Family entity)
{
if (entity == null) return null;
var dto = new FamilyDTO();
dto.FamilyCode = entity.FamilyCode;
dto.FamilyName = entity.FamilyName;
dto.CreateDatetime = entity.CreateDatetime;
dto.Updates_ID = entity.Updates.Select(p => p.ID).ToList();
entity.OnDTO(dto);
return dto;
}
When I run the assembler I find each resulting FamilyDTO has the Updates_ID list populated, although lazy loading is set to true for the EF model (edmx file). Is it possible to configure EntitiesToDTOs to support lazy loading of child elements or will it always use eager loading? I can't see any option in EntitiesToDTOs that could be set to support lazy loading when generating the assembler.
By the way, I'm part of a larger team that uses EntitiesToDTOs to regenerate the assemblers on an almost daily basis, so I'd prefer not to modify the assembler by hand if possible.
I'm Fabian, creator of EntitiesToDTOs.
First of all, thanks a lot for using it.
What you have detected is in fact what I don't want the Assembler to do, I want the developer to map the navigation properties only if needed using the partial methods OnDTO and OnEntity. Otherwise you run into problems like you have.
Seems like I never run into that problem using the tool, THANKS A LOT.
So right now I'm fixing this. It's now fixed in version 3.1.
Based on the code that you've posted here, and based on how I think someone would implement such a solution (i.e. to convert records to a DTO format) I think that you would have no choice but to do eager loading.
Some key points:
1) Your Updates_ID field is clearly a List, which means that it's hydrating the collection right away (ToList always executes. Only a regular IEnumerable employs deferred execution).
2) If you're sticking any sort of navigation property in a DTO it would automatically be loaded eagerly. That's because once you so much as touch a navigation property that was brought back by Entity Framework, the framework automatically loads it from the database, and doesn't care that all you wanted was to populate a DTO with it.
Is there a version of the DataLoadOptions class that exists in LINQ to SQL for LINQ to Entities? Basically I want to have one place that stores all of the eager loading configuration and not have to add .Include() calls to all of my LINQ to Entities queries. Or if someone has a better solution definitely open to that as well.
TIA,
Benjy
Personally I'm glad that there is no (official) EF equivalent of DataLoadOptions. Why? A few reasons:
It is too easy to use them in a way that exceptions are thrown, see the remarks section of the MSDN page.
I don't like the concept of filtered child collections. When a Customer has Orders, I want the Orders member to represent the orders of that customer (lazy or not). A filter defined somewhere else (by AssociateWith) is easily forgotten. I will filter them when and where needed. This leads to the last objection:
Most importantly: it is stateful and most bugs are caused by unexpected state. DataLoadOptions change the DataContext's state in a way that later queries are influenced. I prefer to define eager loading where and when I need it. Typing is cheap, bugs are expensive.
Nevertheless, for completeness's sake I should mention that Muhammad Mosa did put some effort in an EF version of DataLoadOptions. I never tried it though.
I realize that you probably want to prevent repetitive code. But if you need identically shaped queries in more than one place you are already repeating code, with or without "globally" defined includes. A central eager loading configuration is pseudo DRY-ness. And soon you'll find yourself tripping over your own feet when eager loading is not desired but, darn, it's configured to happen!
Entity Framework does not support eager loading settings for the whole 'ObjectContext'. But you can declare all required 'IQueryable' properties with include options in a partial class. For example:
public IQueryable<Order> Orders {
get {
return OrderSet.Include("OrderDetails");
}
}
In the ADO.Net Entity Framework, I have an object which has 4 references to other objects. For some reason, when I query those references, two of them load automatically (as expected), and two of them always return null.
Bizarrely enough, when I manually ask the references to load, they load just dandy.
As an example:
if (account.HoldingEntity == null &&
account.HoldingEntityReference.EntityKey != null) {
account.HoldingEntityReference.Load();
account.HoldingEntity = account.HoldingEntityReference.Value;
}
When I first check the HoldingEntity it is always null, however the Load will return the HoldingEntity without problem.
Any clues?
Thanks!
Using ADO.NET Entities, you need to specify what entities you want to load automatically with Include, as in
Dim entity = (From e in db.Entities.Include("SubEntity"))
As others have said you need to .Include() in v1 to avoid needing to call .Load()
In 4.0 you will be able to set DeferredLoadingEnabled on your ObjectContext (I think we are changing this name to the more appropriate LazyLoadingEnabled in time for Beta2).
As for why you get 2 relationships already loaded anyway. That is probably a side-effect of something called Relationship Fix-up.
When two related entities are in the same Context, they automatically get their relationship's fixed to point to each other. So if (as I suspect) 2 of the 4 entities are already in your context, when you do the query, you will end up in a situation where 2 of your relationships are loaded, even though you didn't call .Include() or .Load().
Hope this helps
Cheers
Alex
This was done in EF v1 as a design decision, and many developers actually prefer having explicit control over if and when referenced properties will be loaded.
For EF v4 coming out with .NET 4.0 before the end of 2009, you'll have the option to turn on automatic deferred loading, if you so wish. See this blog post on the ADO.NET team blog for more information on deferred loading in EF v4.
Marc
I have been puzzling over a problem this morning with LinqToSQL. I'll try and summarise with the abbreviated example below to explain my point.
I have DB two tables:
table Parent
{
ParentId
}
table Child
{
ChildId
ParentId [FK]
Name
Age
}
These have LinqToSQL equivalent classes in my project, however, I have written two custom model classes that I want my UI to use, instead of using the LinqToSQL classes.
My data access from the front end goes through a service class, which in turn calls a repository class, which queries the data via linq.
At the repository level I return an IQueryable by:
return from data in _data.Children
select new CustomModel.Child
{
ChildId = data.ChildId,
ParentId = date.ParentId
};
My service layer then adds an additional query restriction by parent before returning the list of children for that parent.
return _repository.GetAllChildren().Where(c => c.Parent.ParentId == parentId).ToList();
So at this point, I get the method has no supported translation to sql error when I run everything as the c.Parent property of my custom model cannot be converted. [The c.Parent property is an object reference to the linked parent model class.]
That all makes sense so my question is this:
Can you provide the querying process
with some rules that will convert a
predicate expression into the correct
piece of SQL to run at the database
and therefore not trigger an error?
I haven't done much work with linq up to now so forgive my lack of experience if I haven't explained this well enough.
Also, for those commenting on my choice of architecture, I have changed it to get around this problem and I am just playing around with ideas at this stage. I'd like to know if there is an answer for future reference.
Many thanks if anyone can help.
Firstly, it begs the question: why is the repository returning the UI types? If the repo returned the database types, this wouldn't be an issue. Consider refactoring so that the repo deals only with the data model, and the UI does the translation at the end (after any composition).
If you mean "and have it translate down to the database" - then basically, no. Composable queries can only use types defined in the LINQ-to-SQL model, and a handful of supported standard functions. Something similar came up recently on a related question, see here.
For some scenarios (unusual logic, but using the typed defined in the LINQ-to-SQL model), you can use UDFs at the database, and write the logic yourself (in TSQL) - but only with LINQ-to-SQL (not EF).
If the volume isn't high, you can use LINQ-to-Objects for the last bit. Just add an .AsEnumerable() before the affected Where - this will do this bit of logic back in managed .NET code (but the predicate won't be used in the database query):
return _repository.GetAllChildren().AsEnumerable()
.Where(c => c.Parent.ParentId == parentId).ToList();