If I have a set of tables, TableA, TableB, TableC and TableD with TableA having one to many relationships with TableB, TableC and TableD.
Sometimes I want to return the entire set of TableA, TableB, TableC and TableD. Sometimes I want to return just TableA.
At the moment I have the following:
TableA tableA;
if (includeRelationships)
{
tableA = (from a in context.TableAs
.Include("Tabl开发者_开发百科eBs")
.Include("TableCs")
.Include("TableDs")
where a.Id = myId
select a).SingleOrDefault();
}
else
{
tableA = (from a in context.TableAs
where a.Id = myId
select a).SingleOrDefault();
}
// do stuff with tableA
Is this the only way to do this?
EDIT - Clarification following feanz's answer:
This will be exposed as a WCF service so it needs to be a single DB call, either all tables or single TableA, so Lazy / Deferred Loading is not an option.
Becasue EF Support Lazy loading by Default the second example:
tableA = (from a in context.TableAs
where a.Id = myId
select a).SingleOrDefault();
Will still have TableBs,TableCs and TableDs as parameters that you can access. The first time these parameters are accessed EF should fire of the query to get the appropriate information. This can be a perf issue and leed to N+1 issues, however in some situations it desirable as like you mentioned you may not want to always get the data.
EF Lazy Loading Info
Do something like this
var query = context.TableA;
if (includeRelationships)
{
query = query.Include("Tableb").Include("TableC").Include("TableD");
}
var tablea = query.SingleOrDefault();
In this case you are using the fact that the extension method "Include" takes and returns an IQueryable. You might want to use the:
query.Include(x => x.TableB)...
overload of the method that takes an expression as a parameter. That way the compiler will do the checking for you. You may not have access to it if you are using an older version of EF.
use
context.ContextOptions.LazyLoadingEnabled = true;
精彩评论