具有多个表和多对多关系的复杂 EntityFramework 查询
我很难让实体框架做我想做的事。我正在编写一个 feed 聚合器,这样我就可以将多个 rss feed 添加到“FeedList”中,该“FeedList”会将所有单独的播客分组并按 pubDate 排序。
类(除了 FeedListFeed 之外的所有类都有名为 Id 的标识列):
- Feed(Id 是标识主键,具有 List Items 属性)
- FeedItem(Id 是标识主键,如 int FeedId 和 Feed Feed 属性)
- FeedList(FeedListName 是字符串和 List Feeds 属性) )
- FeedListFeed (多对多链接表、FeedListId 和 FeedId 属性)
这些映射似乎有效:
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"));
现在我想做的是获取最新的 20 个 FeedListItem 条目给定 FeedListName 的 FeedList。我已经想到了这个,但是有更好的方法吗?该查询是否会真正扩展所有项目,或者它是否足够智能,可以在 SQL 端执行此操作?
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();
如果我尝试使用 Id 列手动链接表,则会收到错误无效的对象名称“dbo.FeedListFeeds1”。
如果我取出将表相互链接的列表,这会有帮助吗?还有其他映射可以让这个工作吗?
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;
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;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
从映射中删除这一行……
因为它有 2 个问题:
1) 如果您想要一个复合键,则不能链接
HasKey
,而是通过匿名类型创建键:2) (更重要的是)此行让 EF 将
FeedListFeed
视为模型中不存在的实体。结果是 EF 为其创建一个名为FeedListFeeds1
的单独表,因为FeedListFeeds
在多对多映射中保留为表名称 (.ToTable (“FeedListFeeds”)
)。对于多对多映射,您不需要为链接表创建类。链接表由 EF 内部管理。编辑
当然,您也可以完全删除
FeedListFeed
类。对于查询,我会尝试:
我认为您的模型类中具有所有必要的导航属性,因此该查询应该是可能的。
Remove this line from your mapping ...
... because it has 2 issues:
1) If you want a composite key you must not chain
HasKey
but create the key via an anonymous type:2) (more important) This line lets EF consider
FeedListFeed
as an entity which it isn't in your model. The result is that EF creates a separate table for it with the nameFeedListFeeds1
becauseFeedListFeeds
is 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
FeedListFeed
class 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.