【问题标题】:Join and sort 2 not related tables加入并排序 2 个不相关的表
【发布时间】:2020-05-19 19:06:10
【问题描述】:

我有 2 个实体:帖子和文章,我需要同时选择它们并按公共属性排序。我正在寻找一些“加入”的可能性,但我发现的只是以 ...where a.id == b.a_id 之类结尾的示例,这与我的情况无关。

这是我的模型

class BaseEntity {
    public int Id;
    public DateTime AddedDate;
}

class Post extends BaseEntity {
    public string Title;
}

class Article extends BaseEntity {
    public string Name;
}

对于该数据:

Articles:
Id | Name | AddedDate
 1 | AAA  | 15/05/2020 18:00:00
 2 | BBB  | 17/05/2020 18:00:00
 3 | CCC  | 19/05/2020 18:00:00

Posts:
Id | Title | AddedDate
 1 | DDD   | 16/05/2020 18:00:00
 2 | EEE   | 18/05/2020 18:00:00
 3 | FFF   | 20/05/2020 18:00:00

当按日期 DESC 排序并将其限制为 4 时,我需要以类似或类似的方式结束:

Article Id | PostId | Name  | Title | AddedDate
NULL       | 3      | NULL  | FFF   | 20/05/2020 18:00:00
3          | NULL   | CCC   | NULL  | 19/05/2020 18:00:00
NULL       | 2      | NULL  | EEE   | 18/05/2020 18:00:00
2          | NULL   | BBB   | NULL  | 17/05/2020 18:00:00

有人能以某种方式给我建议吗?我需要在 EF Core 中执行此操作。

我可以像这样构造整个列表并对其进行操作,但这远非最佳:

var results = (new List<BaseEntity>()).Concat(_context.Posts.ToList());
results = results.Concat(_context.Articles.ToList()).ToList();

//order
//take(x)

【问题讨论】:

标签: c# entity-framework entity-framework-core


【解决方案1】:

要获得您需要的结果,您必须将 PostArticle 都投影到共享类型,所以首先我创建了一个 ResultDto - 这是您想要获得的类型的表示:

    public class ResultDto
    {
        public int? ArticleId { get; set; }
        public int? PostId { get; set; }
        public string Name { get; set; }
        public string Title { get; set; }
        public DateTime AddedDate { get; set; }
    }

然后你必须将Aritles投影到ResultDto,以及将Post投影到ResultDto,连接结果并像这样排序:

            var result = _dbContext
                .Articles.Select(a => new ResultDto()
                {
                    ArticleId = a.Id,
                    AddedDate = a.AddedDate,
                    Name = a.Name,
                    PostId = null,
                    Title = null
                }).Concat(_dbContext.Posts.Select(p => new ResultDto()
                {
                    PostId = p.Id,
                    AddedDate = p.AddedDate,
                    Title = p.Title,
                    ArticleId = null,
                    Name = null
                }))
                .OrderByDescending(r => r.AddedDate)
                .ToList();

顺便说一句,由于在 IQuerable 上调用了此 Select,您将必须选择所有属性(即使它们默认为 NULL)。

这会导致以下 SQL 查询:

    SELECT [t].[ArticleId], [t].[AddedDate], [t].[Name], [t].[PostId], [t].[Title]
      FROM (
          SELECT [a].[Id] AS [ArticleId], [a].[AddedDate], [a].[Name], NULL AS [PostId], NULL AS [Title]
          FROM [Articles] AS [a]
          UNION ALL
          SELECT NULL AS [ArticleId], [p].[AddedDate], NULL AS [Name], [p].[Id] AS [PostId], [p].[Title]
          FROM [Posts] AS [p]
      ) AS [t]
      ORDER BY [t].[AddedDate] DESC

【讨论】:

猜你喜欢
  • 2020-02-25
  • 2019-12-29
  • 1970-01-01
  • 2011-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多