Reputation: 5239
I'm having trouble getting all the data out of the database and I'm not entirely sure what I'm doing wrong, pretty much all of this is new to me.
I've searched SO and found the following question which seems pretty similar to mine - Repository Pattern for Entity Framework and Children Objects
I've looked at the answer which contained this link but I'm struggling to get this to work.
I have my campaign repository which returns a campaign. It returns the list of Audits as expected but the Audits don't have the Comments or the CampaignAction in them. Is there something special I need to do to tell the DB to pull out all the cascading objects?
Thanks for any help
Neil
public override Campaign Get(int id)
{
var query = Context.Campaigns.Include(x => x.Audits)
.FirstOrDefault(c => c.CampaignId == id);
if (query != null)
Logger.Trace(query.ToString());
return query;
}
I have my campaign class
public class Campaign
{
public Campaign()
{
Audits = new Collection<Audit>();
}
public int CampaignId { get; set; }
[StringLength(40, ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "CampaignModel_Name_StringLength")]
[Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "CampaignModel_Name_Required")]
[Display(Name = "CampaignModel_Name", ResourceType = typeof(Resources.Resources))]
public string Name { get; set; }
public ICollection<Audit> Audits { get; set; }
}
And my audit class
public class Audit
{
public Audit()
{
Comments = new Collection<Comment>();
}
public int AuditId { get; set; }
[Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "Audit_CampaignAction_Required")]
[Display(Name = "Audit_CampaignAction", ResourceType = typeof(Resources.Resources))]
public CampaignAction Action { get; set; }
[Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "Audit_UserName_Required")]
[Display(Name = "Audit_UserName_Content", ResourceType = typeof(Resources.Resources))]
public string UserName { get; set; }
[Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "Audit_TimeStamp_Required")]
[Display(Name = "Audit_TimeStamp", ResourceType = typeof(Resources.Resources))]
public DateTime TimeStamp { get; set; }
public ICollection<Comment> Comments { get; set; }
[JsonIgnore]
public virtual ICollection<Campaign> Campaigns { get; set; }
}
Upvotes: 1
Views: 352
Reputation: 1117
As long as you use eager loading, you have to call Include()
on all entities, that you want to have loaded from database. This rule applies for child entities (Audits), but also for grandchilds (Action and Comments).
Normally you would use simple dot-notation to include grandchilds, but if the child entity is a collection, there is a special syntax using the Select()
method.
Your query should look like
var query = Context.Campaigns.Include(x => x.Audits)
.Include(x => x.Audits.Select(a => a.Comments))
.Include(x => x.Audits.Select(a => a.Action))
.FirstOrDefault(c => c.CampaignId == id);
Upvotes: 2