Entity Framework 4 - Как ограничить количество дочерних элементов из другой таблицы (связанных через внешний ключ) - PullRequest
3 голосов
/ 09 апреля 2011

У меня есть две модели данных Блог и Пост . 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);
}

Ответы [ 2 ]

3 голосов
/ 09 апреля 2011

К сожалению, 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();

Edit:

Вы можете сделать это в одном запросе с проекцией:

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

Просто имейте в виду, что вы должны получить доступ к сообщениям со второго параметра анонимного типа.

0 голосов
/ 09 апреля 2011

Вы имеете в виду:

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