如何使用SelectMany展平集合

时间:2015-10-05 15:30:21

标签: c# entity-framework

我有以下实体(I18N是本地化实体):

public class Post { 
  public Int32 Id { get; set; }
  public Boolean IsPublished { get; set; }
  public List<PostI18N> PostsI18N { get; set; }
  public List<Tag> Tags { get; set; }
  public Author { get; set; }
}

public class Tag { 
  public List<TagI18N> TagsI18N { get; set; }
}

public class Author { 
  public Int32 Id { get; set; }
  public String Name { get; set; }
}

public class PostI18N { 
  public Int32 Id { get; set; }
  public String Text { get; set; }
  public String Title { get; set; }
}

public class TagI18N { 
  public Int32 Id { get; set; }
  public String Name { get; set; }
}

我需要获取4个帖子的所有信息,所以我试图弄平查询:

var posts = await _context
    .Posts
    .SelectMany(x => x.PostsI18N, (Post, PostI18N) => 
       new { Post, PostI18N, Post.Tags, Post.Author })
    .Where(x => x.PostI18N.Language == "en")
    .Select(x => new PostDTO {
       Id = x.Post.Id,
       Title = x.PostI18N.Title,
       Text = x.PostI18N.Text,
       AuthorName = x.Author.Name
       TagsNames = // Names taken from x.Tags.TagsI18N where TagsI18N
                   // language is "en" ... So, for each tag look the 
                   // one Tag.TagI18N which Tag.TagI18N.Language = "en"
                   // and get Tag.TagI18N.Name
    })
    .Take(4)
    .ToListAsync();

问题: 问题是我还需要将TagsI18N弄平,所以我可以将他们的名字用于英语...

SelectMany可以实现吗?我该怎么做?

1 个答案:

答案 0 :(得分:1)

请在查询语法中尝试:

var posts = await (
    from p in _context.Posts
    from pn in p.PostsI18N
    where pn.Language == "en"
    select new PostDTO {
        Id = p.Id,
        Title = pn.Title,
        Text = pn.Text,
        AuthorName = p.Author.Name,
        TagsNames = from t in p.Tags
                    from tn in t.TagsI18N
                    where tn.Language == "en"
                    select tn.Name
    }).Take(4).ToListAsync();

SelectMany语法也可以正常工作,但它有点&#34;嵌套&#34;:

var posts = await _context
    .Posts
    .SelectMany(x => x.PostsI18N, (Post, PostI18N) => 
        new { Post, PostI18N, Post.Tags, Post.Author })
    .Where(x => x.PostI18N.Language == "en")
    .Select(x => new PostDTO {
        Id = x.Post.Id,
        Title = x.PostI18N.Title,
        Text = x.PostI18N.Text,
        AuthorName = x.Author.Name
        TagsNames =
            x.Tags.SelectMany(t => t.TagsI18N, (Tag, TagI18N) =>
                new { Tag, TagI18N })
            .Where(t => t.TagI18N.Language == "en")
            .Select(t => t.TagI18N.Name)
    })
    .Take(4)
    .ToListAsync();