基于linq中的链接表在select中创建新对象

时间:2016-08-09 20:38:26

标签: c# .net linq

我有一张表到另一张表的FK。我正在使用"视图模型"我想要返回的类而不是实际的EF类。我知道我可以加入第2个表并过滤第一个表,然后根据我想要的字段在select部分中创建一个新的视图模型,但是我可以在没有连接的情况下执行此操作,而是使用链接表(通过FK )在select中创建视图模型实例?

即。这有效:

return (from a in context.Articles
                    join t in context.Topics on a.TopicID equals t.Id
                    where t.Name == topic
                    select new ArticleViewModel { Title = a.Title, Introduction = a.Introduction, Content = a.Content }).ToList();

我可以用简短的方式创建带有Topics.Article链接的ArticleViewModel:

return (from t in context.Topics
                    where t.Name == topic
                    select /*how can I create ArticleViewModel from t.Articles?*/ t.Articles).ToList();

2 个答案:

答案 0 :(得分:1)

不是HQL而是Linq,我不认为你可以在HQL中选择多个,所以你的左边做了连接,或者是子查询...

context.Topics.Where(x => x.Name.Equals(topic))
              .SelectMany(y => y.Articals)
              .Select(z => new ArticalViewModel { Title = z.Title , etc.. });

答案 1 :(得分:1)

看来你有一个DbContext

  • 使用DbSet文章。每篇文章都有一个主题。
  • 使用DbSet主题。每个主题都有一组属于该主题的文章。
  • 并且您希望属于主题的所有文章都具有变量主题的值。

如果您使用实体框架,并且您在主题课程中拥有一对多的关系,那么"很多" part有一个外键,一个"一个"和#34;一个" part有一个虚拟ICollection的"很多"部分

文章只属于一个主题。一篇文章"有"一个主题。

主题包含一系列文章。该集合的每个项目都属于该主题。

设计如下:

public class Article
{
    public int Id {get; set;}       // by convention will become primary key
    public int TopicId {get; set;}  // by convertion will become foreign key to Topic
    public Topic Topic {get; set;}  // an article "has" a Topic
    public string Title {get; set;}
    public string Introduction {get; set;}
    // etc.
}

public class Topic
{
    public int Id {get; set;}       // by convention primary key

    public virtual ICollection<Article> Articles {get; set;}
    ...
    // other Topic properties
}

public class MyDbContext : DbContext
{
    public DbSet<Topic> Topics {get; set;}
    public DbSet<Article> Articles {get; set;}
}

以下Linq语句将获取您的ArticleViewModel项序列 (我把它们分成小步,这样就可以清楚地发生了什么

using (var context = new MyDbContext(...))
{
    IQueryable<Article> articlesOfTopicsWithTopicName = context.Topics
        .Where(topc=> topc.Name == myTopicName)
        .SelectMany(topic => topic.Articles);

每当你有一个A类序列并且每个A都有一个B类序列,并且你想要所有B对象时,你就使用SelectMany。

    IQueryable<ArticleViewModel> requestedItems =
        articlesOfTopicsWithTopicName.Select(article =>
            new ArticleViewModel()
            {
                Title = article.Title,
                Introduction = article.Introduction,
                ...
            }
    // delayed execution, nothing has been performed yet
    return requestedItems.ToList();
    // execute and return the list
}

如果您使用数据库分析器,您将看到selectMany将在主题

中具有主键的文章中对外键进行连接