I am using code first and entity framework.
I have a Registration
entity which has several properties of other models:
public class Registration
{
public int ID { get; set; }
public int OrganizationID { get; set; }
public Address 开发者_如何学GoRegAddress { get; set; }
public ContactInformation RegContactInformation { get; set; }
public string Signature{ get; set; }
}
With this setup, I do have an Address
and ContactInformation
model. When I save a registration it works as I would expect. A database with 3 tables (Registration
, Address
, and ContactInformation
). With the Registration
having FK to the other two.
However when I try and get the registrations from my database using EF:
DBConnections dbConnections = new DBConnections();
var registrations = from r in dbConnections.PlayerRegistrations
where r.OrganizationID == orgID
select r;
The Registration.Address and Registration.ContactInformation
is null. How can I make this work?
That is correct behavior because EF never loads related entities itself. To load related properties you must use one of following approaches:
Lazy loading
Lazy loading will provide you automatic loading of related entities but it will generate additional queries to the database. Related entity or related collection will be loaded when you access the property for the first time. To use lazy loading you must mark all navigation properties in the entity as virtual
(also lazy loading or proxy creation mustn't be disable - it is allowed by default). Lazy loading works only if the context used to load the main entity is still alive. To allow lazy loading you must modify your entity:
public class Registration
{
public int ID { get; set; }
public int OrganizationID { get; set; }
public virtual Address RegAddress { get; set; }
public virtual ContactInformation RegContactInformation { get; set; }
public string Signature{ get; set; }
}
Eager loading
Eager loading will define which relation must be load together with your main entity. Eager loading is defined by Include
method. You can rewrite Find as:
var registrations = from r in dbConnections.PlayerRegistrations
.Include(p => p.Address)
.Include(p => p.RegContactInformation)
where r.OrganizationID == orgID
select r;
Be aware that eager loading has big impact on the amount and form of data returned from database.
Explicit loading
Explicit loading will allow you to explicitly saying that some relation should be loaded. You can even define some condition for loading related entities which is not possible with other two methods. You must first load the main entity and before disposing the context you can do something like:
context.Entry(registration).Reference(c => c.Address).Load();
This method is more useful for loading related collections.
Custom loading
Custom loading means that you will use separate query for each relation. It looks like something you don't want to do but for some performance optimization of transferred result sets this can be very useful (this solves problem linked in eager loading part). The point of this method is that if you use separate query for relation EF will still correctly fill navigation properties. This method makes sense only for loading related collections and it works only if lazy loading is turned off.
精彩评论