views:

33

answers:

3

Hello, another Entity Framework (ADO.NET) question from me. I'm using EF1 (no choice there) and have a MySQL database as a backend.

A simple question I can't really find a satisfying answer for:

What exactly do I have to do for loading? IE., when I have an entity and want to enumerate through its children, say I have the Entity "Group" and it has a child "User", and I want to do "from n in g.Users where n.UserID = 4 select n", I first have to call g.Users.Load();

This is a bit annoying, because when I do a query against a non-loaded collection, I would expect the EF to load it automatically - AT LEAST throw some exception, not simply return 0 results?

Another case of me having to take care of loading: I have a query:

from n in Users where n.Group.Name == "bla" select n

For some reason it fails, giving a null pointer for n.Group, even though n.GroupID (the key for the group) is correctly set. Also, when I before do Server.Groups.Load() (Groups are children of one Server), it works.

Is there any exact policy about when to call Load() of which collection?

Thank you again, Michael

+1  A: 

Do you mean ObjectQuery.Include, e.g.

var g = from g in MyDb.Groups.Include("Users") where g.Id = 123 select g;
from n in g.Users where n.UserID = 4 select n

from n in Users.Include("Group") where n.Group.Name == "bla" select n

You can also wrap Load()s in a check if you're worried about over-using them,

if (g.CanLoadReferences() && !g.Users.IsLoaded)
{
    g.Users.Load();
}

(apologies for any silly syntax slips here - I use the other LINQ syntax and EF4 now)

Rup
Unfortunately Include() doesn't solve my issue:Server.Groups is an EntityCollection<> which doesn't have an Include() method..And thanks for the check, but my "problem" is that I don't see why the framework doesn't load the entities itself when I make a query against a non-loaded collection... So I don't want to have to call Load() at all (I know it sounds lazy, but I thought the whole idea of ORM was to provide easy access to RM data via simple collections etc.)
Michael
Ah, OK, sorry. You'd need to use the Include on the Servers EntitySet then - sorry I misunderstood which object that was. But then you get the data loaded for all values whether you ultimately end up using them or not. Yeah, unfortunately lazy loading like that is an EF4 feature.
Rup
Alright, thank you very much for that explanation :-)Guess I'll have to stick with manually loading the data!
Michael
A: 

This works when we run against MS SQL server, it could be a limitation in the MySQL Adapter.

Are you using the latest version 6.2.3? See: http://www.mysql.com/downloads/connector/net

Shiraz Bhaiji
+2  A: 

There is no lazy loading in the first version of entity framework. Any time you want to access something you have not previously loaded, be it a reference to a single object or a collection of objects, you will either have to explicitly tell it to load that reference. The Include() option (first from Rup above) is going to try to load all the data you want in one large query and processing call, the result being that Include() performs slowly. The other method (2nd from Rup above), checking and then loading unloaded references, performed much faster and allowed us to limit loads to what we needed.

Basically our policy was to load only what you had to in the initial query, minimizing performance impact. Then we would check and load the reference later when we wanted to access a referenced entity or entity collection. This resulted in more queries to the database, but they were faster and we were only loading the ancillary data when we needed it, instead of pre-loading everything we could potentially need. It was possible that the same property would get checked as couple times in a function, but it would only have been loaded once and we could be sure we were only loading it because we were using it.

Tarwn
Thank you for the information!I'll manually load the data via Load()!
Michael