简体   繁体   中英

LINQ to Entities returns wrong ID for an entity's child's child

I have a table structure in MySql, set up with foreign keys:

Period { Id, Title }

Activity { Id, Title, PeriodId }

Resource { Id, FileName }

ActivityResources { ActivityId, ResourceId }

This is set up with LINQ-to-Entities and I have checked that the table mappings are correct incuding the many-to-many relationship. Normally all works well with the Period , Activity and Resource classes.

However, I am trying to use this code:

private string ListAttachments(Ctx ctx) {
  var resList = new StringBuilder();
  var p = ctx.Periods.Include("Activities.Resources").Single(o => o.Id == 1);
  foreach (var a in p.Activities) foreach (var r in a.Resources)
    resList.Append(r.Id).Append(" - ").Append(r.FileName);
  return resList.ToString();
}

But it doesn't write the Resource.Id for each resource as expected; for some reason it writes the Activity.Id instead (though the FileName is correct).

Any idea what's going on?

EDIT

By the way, this works fine - but I'm still interested in the probem in the above code.

private string ListAttachments(Ctx ctx) {
  var resList = new StringBuilder();
  var res = ctx.Resources.Where(r => r.LessonActivities.Any(l => l.LessonId == 1)).ToList();
  foreach (var r in res) resList.Append(r.Id).Append(" - ").Append(r.FileName);
  return resList.ToString();
}

I don't think you can reference a child/child collections that way. The Activities navigation property on a Period object is a collection. And you can't reference a property that belongs to an instance of an object via a collection of those objects.

Put another way, Period p has an Activities collection. But a collection of type Activity does not have a Resources collection. Only a single Activity has a Resources collection.

What I don't understand is why the first snippet works at all.

Anyway, to get to the Resources collection directly from a Period , you would need to use SelectMany() . Something like

List<Resource> resources = ctx.Periods
                              .Where(p=>p.Id == 1)
                              .SelectMany(p=>p.Activities)
                              .SelectMany(a => a.Resources)
                              .ToList();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM