实体框架 4 - 如何限制另一个表中的子元素数量(通过外键连接)

发布于 2024-10-31 04:26:25 字数 707 浏览 0 评论 0原文

我有两个数据模型博客帖子。 BlogId 是 Post 表上的外键

public class Blog
{
   public int ID { get; set; }

   public string Title { get; set; }

   public virtual ICollection<Post> Posts { get; set; }

  ...  
}


public class Post
{
   public int ID { get; set; }

   public virtual int BlogId { get; set; }

   public string Title { get; set; }

  ...  
}

现在这工作正常,我的存储库很高兴并按预期从数据库中提取所有内容。

我的问题是 - 有没有办法限制检索的帖子数量。也许有一些 LINQ 魔法?

这是我在存储库中当前方法的样子:

public Business FindBlog(int id)
{
    return this.context.Get<Blog>().SingleOrDefault(x => x.ID == id);
}

I have two data models Blog and Post. BlogId is a foreign key on the Post table

public class Blog
{
   public int ID { get; set; }

   public string Title { get; set; }

   public virtual ICollection<Post> Posts { get; set; }

  ...  
}


public class Post
{
   public int ID { get; set; }

   public virtual int BlogId { get; set; }

   public string Title { get; set; }

  ...  
}

Now this works fine and my Repository is happy and pulls everything as expected from DB.

My question is - Is there a way to limit the number of Posts that get retrieved. Perhaps some LINQ magic?

Here is what my current method in the repository looks like:

public Business FindBlog(int id)
{
    return this.context.Get<Blog>().SingleOrDefault(x => x.ID == id);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(2

吾性傲以野 2024-11-07 04:26:25

不幸的是,EFv4 没有提供简单的方法来限制导航属性返回的记录数量。

如果您使用 EntityObject 派生实体,您可以使用类似的内容:

var blog = context.Blogs
                  .Single(b => b.Id == blogId);

var posts = blog.Posts
                .CreateSourceQuery()
                .OrderByDescending(p => p.Date)
                .Take(numberOfRecords)
                .ToList();

如果您使用 POCO,则必须为此执行单独的查询(如果是代理 POCO,您可以 将导航属性转换为EntityCollection< ;Post> 访问 CreateSourceQuery):

var blog = context.Blogs
                  .Single(b => b.Id == blogId);

var posts = context.Posts
                   .Where(p => p.BlogId == blogId)
                   .OrderByDescending(p => p.Date)
                   .Take(numberOfPosts)
                   .ToList();

EFv4.1 和 DbContext API 提供了仅加载有限数量的相关实体的方法:

var blog = context.Blogs
                  .Single(b => b.Id == blogId);

context.Entry(blog)
       .Collection(b => b.Posts)
       .Query()
       .OrderByDescending(p => p.Date)
       .Take(numberOfPosts)
       .Load();

编辑:

您可以通过投影在单个查询中完成此操作:

var blog = context.Blogs
                  .Where(b => b.Id == blogId)
                  .Select(b => new 
                      {  
                          Blog = b,
                          Posts = b.Posts
                                   .OrderByDescending(p => Date)
                                   .Take(numberOfRecords)
                      })
                  .SingleOrDefault()

请注意,您必须从匿名类型的第二个参数访问帖子。

Unfortunatelly EFv4 doesn't offer easy way to limit number of returned record for navigation property.

If you are using EntityObject derived entities you can use something like:

var blog = context.Blogs
                  .Single(b => b.Id == blogId);

var posts = blog.Posts
                .CreateSourceQuery()
                .OrderByDescending(p => p.Date)
                .Take(numberOfRecords)
                .ToList();

If you are using POCOs you must execute separate query for that (in case of proxied POCOs you can convert navigation property to EntityCollection<Post> to get access to CreateSourceQuery):

var blog = context.Blogs
                  .Single(b => b.Id == blogId);

var posts = context.Posts
                   .Where(p => p.BlogId == blogId)
                   .OrderByDescending(p => p.Date)
                   .Take(numberOfPosts)
                   .ToList();

EFv4.1 and DbContext API offers the way to load only limited number of related entities:

var blog = context.Blogs
                  .Single(b => b.Id == blogId);

context.Entry(blog)
       .Collection(b => b.Posts)
       .Query()
       .OrderByDescending(p => p.Date)
       .Take(numberOfPosts)
       .Load();

Edit:

You can do it in single query with projection:

var blog = context.Blogs
                  .Where(b => b.Id == blogId)
                  .Select(b => new 
                      {  
                          Blog = b,
                          Posts = b.Posts
                                   .OrderByDescending(p => Date)
                                   .Take(numberOfRecords)
                      })
                  .SingleOrDefault()

Just be aware that you must access posts from second paremeter of anonymous type.

喜爱纠缠 2024-11-07 04:26:25

您的意思是:

public List<Post> GetBlogPosts(Blog blog, int numberOfPosts)
{
    return blog.Posts.Take(numberOfPosts);
}

Do you mean:

public List<Post> GetBlogPosts(Blog blog, int numberOfPosts)
{
    return blog.Posts.Take(numberOfPosts);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文