I’m having a heck of a time getting Entity Framework to do what I want. I’m writing a feed aggregator so I can add multiple rss feeds to a “FeedList” that will group all the individual podcasts and order by pubDate.
Classes (all but FeedListFeed have identity column called Id):
- Feed (Id is identity primary key, has List Items property)
- FeedItem (Id is identity primary key, as int FeedId and Feed Feed properties)
- FeedList (FeedListName is string and List Feeds property)
- FeedListFeed (many-to-many linking table, FeedListId and FeedId properties)
These mappings seems to work:
modelBuilder.Entity<FeedListFeed>().HasKey(x => x.FeedId).HasKey(x => x.FeedListId);
modelBuilder.Entity<FeedList>()
.HasMany(fl => fl.Feeds).WithMany(f => f.FeedLists)
.Map(t => t.MapLeftKey("FeedListId")
.MapRightKey("FeedId")
.ToTable("FeedListFeeds"));
Now what I want to do is get the latest 20 FeedListItem entries for Feeds in a FeedList given the FeedListName. I’ve come up with this, but is there a better way to do it? Will the query actually expand all the items, or will it be smart enough to do it on the SQL side?
var query =
from fl in ctx.FeedLists.Include("Feeds").Include("FeedItems")
from f in fl.Feeds
from fi in f.Items
where fl.FeedListName == id
orderby fi.PubDate descending
select fi;
List<FeedItem> items = query.Take(20).ToList();
If I try to link the tables manually using the Id columns, I get the error Invalid object name 'dbo.FeedListFeeds1'. If I took out the Lists that link the tables to each other would this help? Is there some other mapping that let this work?
var query =
from fl in ctx.FeedLists
join flf in ctx.FeedListFeeds on fl.Id equals flf.FeedListId
join fi in ctx.FeedItems on flf.FeedId equals fi.FeedId
where fl.FeedListName == id
orderby fi.PubDate descending
select fi;
Remove this line from your mapping …
… because it has 2 issues:
1) If you want a composite key you must not chain
HasKeybut create the key via an anonymous type:2) (more important) This line lets EF consider
FeedListFeedas an entity which it isn’t in your model. The result is that EF creates a separate table for it with the nameFeedListFeeds1becauseFeedListFeedsis reserved as table name in your many-to-many mapping (.ToTable("FeedListFeeds")). For many-to-many mapping you don’t need to create a class for the linking table. The linking table is managed by EF internally.Edit
You can then also remove the
FeedListFeedclass completely of course.For the query I would try then:
I think you have all the necessary navigation properties in your model classes so that this query should be possible.