具有多个表和多对多关系的复杂 EntityFramework 查询

发布于 2024-11-07 06:23:58 字数 1503 浏览 0 评论 0原文

我很难让实体框架做我想做的事。我正在编写一个 feed 聚合器,这样我就可以将多个 rss feed 添加到“FeedList”中,该“FeedList”会将所有单独的播客分组并按 pubDate 排序。

类(除了 FeedListFeed 之外的所有类都有名为 Id 的标识列):

  1. Feed(Id 是标识主键,具有 List Items 属性)
  2. FeedItem(Id 是标识主键,如 int FeedId 和 Feed Feed 属性)
  3. FeedList(FeedListName 是字符串和 List Feeds 属性) )
  4. 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):

  1. Feed (Id is identity primary key, has List Items property)
  2. FeedItem (Id is identity primary key, as int FeedId and Feed Feed properties)
  3. FeedList (FeedListName is string and List Feeds property)
  4. 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

心凉怎暖 2024-11-14 06:23:58

从映射中删除这一行……

modelBuilder.Entity<FeedListFeed>()
            .HasKey(x => x.FeedId)
            .HasKey(x => x.FeedListId);

​​因为它有 2 个问题:

1) 如果您想要一个复合键,则不能链接 HasKey,而是通过匿名类型创建键:

modelBuilder.Entity<FeedListFeed>()
            .HasKey(x => new { x.FeedId, x.FeedListId });

2) (更重要的是)此行让 EF 将 FeedListFeed 视为模型中不存在的实体。结果是 EF 为其创建一个名为 FeedListFeeds1 的单独表,因为 FeedListFeeds 在多对多映射中保留为表名称 (.ToTable (“FeedListFeeds”))。对于多对多映射,您不需要为链接表创建类。链接表由 EF 内部管理。

编辑

当然,您也可以完全删除 FeedListFeed 类。

对于查询,我会尝试:

var query = from fi in ctx.FeedItems
            where fi.Feed.FeedLists.Any(fl => fl.FeedListName == id)
            orderby fi.PubDate descending
            select fi;

我认为您的模型类中具有所有必要的导航属性,因此该查询应该是可能的。

Remove this line from your mapping ...

modelBuilder.Entity<FeedListFeed>()
            .HasKey(x => x.FeedId)
            .HasKey(x => x.FeedListId);

... 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:

modelBuilder.Entity<FeedListFeed>()
            .HasKey(x => new { x.FeedId, x.FeedListId });

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 name FeedListFeeds1 because FeedListFeeds 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:

var query = from fi in ctx.FeedItems
            where fi.Feed.FeedLists.Any(fl => fl.FeedListName == id)
            orderby fi.PubDate descending
            select fi;

I think you have all the necessary navigation properties in your model classes so that this query should be possible.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文