My questions is probably very simple, how do you load children/subclasses. There is no "load" or anything like it that I can find to have the context load the children.
the context class is of ObjectContext type, see below:
public partial class RTIPricingEntities : global::System.Data.Objects.ObjectContext
Product
Product.ModifiedByUser (how to load this class, when loading product??)
Product.Category (how to load the categories when loading product?)
You can eager load:
var q = from p in Context.Products
.Include("ModifiedByUser")
.Include("Category")
select p;
...or project:
var q = from p in Context.Products
select new
{
Id = p.Id,
Name = p.Name
ModifiedByUserName = p.ModifiedByUser.Name,
CategoryName = p.Category.Name
}
The advantage of projection is you get only the data you need, not the whole of every referenced entity. Advantage of eager loading is that returned entities do change tracking. Pick the right technique for the problem at hand.
Update
Yes, it is important to mention that you are using RIA Services. I presume you're also working within the client. This makes things completely different.
In RIA Services, it is very important to make sure that you return the entire graph of entities you require in the initial load. You don't want to call anything like .Load() on an entity, because that would be another hot to the server, which is bad for performance. If you are in, for example, a Silverlight client and request a list of instances from the server and their related properties are not already materialized, it is already too late. Also, Include will not work within a Silverlight client. Therefore, RIA Services has server-side tools you can use to ensure that you return the correct, fully materialized object graph initially.
What you need to do instead is used IncludeAttribute inside your RIA Services server. You can create a "buddy" metadata class to decorate your entity model with [Include]. There are examples in the RIA Services overview document, section 4.8.
Using the .Include()
as many others have suggested is a great way to achieve what you need.
However, sometimes you might need to "re-load" something later on that you didn't "include", or that you only need sometimes, so putting an Include statement might be a waste of computing cycles in many cases.
In case of a singular relationship like "Product.Category" (where Product.Category is your navigation property from product to category), you most likely also have a "Product.CategoryReference" element. You can check that to see if it's loaded or not, and if not, you can load it "on demand":
if(!Product.CategoryReference.IsLoaded)
{
Product.CategoryReference.Load();
}
Now your referenced "Category" should be in memory and ready to use.
If you have a navigation property which references a collection of things (e.g. "Parts" for a product), you can do the same thing, directly on the navigation property:
if(!Product.Parts.IsLoaded)
{
Product.Parts.Load();
}
That can be a useful technique for "loading on demand" of single or collection type navigation properties if you haven't "included" them into your EF query.
Marc
You can use the Include() method of the System.Data.Objects.ObjectQuery. This method specifies the related objects to include in the query results and calls to Include() can be chained together to load multiple related objects.
For example to load ModifiedByUser and Category you would use a query like this:
var q = from p in context.Products.Include("ModifiedByUser").Include("Category")
select p;
If your Category entity also had a ModifiedByUser entity that you wanted to load you would use a query like this:
var q = from p in context.Products
.Include("ModifiedByUser")
.Include("Category.ModifiedByUser")
select p;
See Shaping Query Results on MSDN for further examples.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With