【问题标题】:How to get specific columns with one to many relationship如何获取具有一对多关系的特定列
【发布时间】:2016-12-04 20:10:32
【问题描述】:

我有 3 个表,一对多的关系。

我只需要使用 SelectMany 方法获取特定列。

我只需要获取所选新闻对象的 Categories.CategoryName 和 Comments.CommentDate。

这是我的代码

News news = db.News.Include(w => w.Categories)
                   .Include(w => w.Comments).SingleOrDefault(n => n.NewsId == Id);

这是我的实体:

新闻实体:

public partial class News
{
    public News()
    {
        this.Categories = new HashSet<Category>();
        this.Comments = new HashSet<Comment>();
    }

    public int NewsId { get; set; }
    public string NewsTitle { get; set; }
    public string NewsBody { get; set; }
    public System.DateTime NewsDate { get; set; }
    public string NewsImagePath { get; set; }

    public virtual ICollection<Category> Categories { get; set; }
    public virtual ICollection<Comment> Comments { get; set; }
}

类别实体:

public partial class Category
{
    public Category()
    {
        this.News = new HashSet<News>();
    }

    public int CategoryId { get; set; }
    public string CategoryName { get; set; }

    public virtual ICollection<News> News { get; set; }
}

评论实体:

public partial class Comment
{
    public Comment()
    {
        this.News = new HashSet<News>();
    }

    public int CommentId { get; set; }
    public string CommentBody { get; set; }
    public Nullable<System.DateTime> CommentDate { get; set; }

    public virtual ICollection<News> News { get; set; }
}

【问题讨论】:

    标签: c# sql-server linq lambda


    【解决方案1】:

    这个 LINQ 查询应该处理它:

    var query =
        from news in db.News
        where news.Id == Id
        let categoryNames =
            from category in news.Categories
            select category.Name
        let commentDates =
            from comment in news.Comments
            select comment.CommentDate
        select new {
            CategoryNames = categoryNames.ToList(),
            CommentDates = commentDates.ToList()
        };
    

    该查询未使用SelectMany,但这对您没有帮助,因为那样您将无法按新闻项对类别和 cmets 进行分组。由于类别和 cmets 没有直接连接,因此您需要两个 SelectManys,然后您需要交叉连接结果。那显然不是你想要的。

    【讨论】:

      【解决方案2】:

      也许尝试使用以下?

      var categoryNames = news.Categories.Select(c=>c.CategoryName);
      var commentDates = news.Comments.Select(c=>c.CommentDate);
      

      注意SelectMany 用于扁平化列表。例如,假设您收集了符合特定搜索条件的新闻,然后您使用SelectMany 收集所有这些新闻的Categories/Comments设置,在一个平面列表中。

      【讨论】:

      • 我不明白这将如何解决问题的问题。它将需要对数据库的两个请求,并且新闻 ID 上没有过滤器。
      • @Sefe 我认为您错过了问题中的第一个代码块。 news 已被 Id 过滤。
      • 我的立场是正确的。您实际上需要对数据库进行 三个 查询。我仍然不明白这是如何替代 SelectMany 查询的可行替代方案,后者只需要一个请求。
      • @Sefe 首先,.Include()s 将急切地加载导致joins 的导航属性,最后使用SingleOrDefault 调用评估/执行查询。因此,news 对象现在与Includeed 路径一起在内存中。因此,从这些集合中选择原始属性将查询内存。所以从技术上讲,数据库之旅是 1.
      • @Sefe 话虽如此,你对你的答案的一个赞成票是我的,因为我认为它非常简洁。所以我认为你不必付出任何其他额外的努力来让 OP 接受你的答案。冷静:)
      猜你喜欢
      • 1970-01-01
      • 2017-04-02
      • 1970-01-01
      • 1970-01-01
      • 2021-10-17
      • 2014-09-01
      • 1970-01-01
      • 2022-06-19
      • 2019-11-25
      相关资源
      最近更新 更多