使用EF Core继承时,如何避免重复属性投影



在EF Core中使用继承时,我正在努力避免重复投影逻辑。

这是我的场景:我有三种类型:

  1. Lesson(这是一个抽象类((属性:IdTitle等(
  2. ArticleLesson(继承自Lesson((属性:ContentTotalWoddsCount等(
  3. VideoLesson(继承自Lesson((属性:VideoUrlDuration等(

几乎所有事情都由EF Core正确处理,我使用默认的每层次表(TPH(方法。

当我想从数据库中检索课程,并且我需要ArticleLessonVideoLesson之间的一些共享列(即Lesson的一些属性(,加上ArticleLessonVideoLesson特定的一些属性时,就会出现问题。这是我想出的表达式:

var r1 = dbContext.Lessons.Select<Lesson, LessonDto>(l =>
    l is ArticleLesson
    ? new ArticleLessonDto
    {
        Id = l.Id, // This is repeated below
        Title = l.Title, // This is repeated below
        // ...other properties that I would have to repeat below
        Content = (l as ArticleLesson).Content,
    }
    : l is VideoLesson
    ? new VideoLessonDto
    {
        Id = l.Id, // This is repeated above
        Title = l.Title, // This is repeated above
        // ...other properties that I would have to repeat above
        VideoUrl = (l as VideoLesson).VideoUrl,
    }
    : null
)
.ToList();

正如您所看到的,我将重复共享属性部分两次。在这个例子中,只有两个属性被重复,IdTitle,但在现实世界中,你可以有几十个;并且必须像这样重复所有这些将是一个h.

有没有办法使这种投影表达更简洁,避免重复?

您可以向LessonDtoArticleLessonDtoVideoLessonDto添加一个接受不同共享属性的构造函数。

    public class LessonDto
    {
        public LessonDto(int id, ... other)
        {
            Id = id;
            // ...
        }
        public int Id { get; set; }
    }
    public class ArticleLessonDto : LessonDto
    {
        public ArticleLessonDto(LessonDto dto) : base(dto.Id)
        {
        }
        public string Content { get; set; }
    }
    var r1 = dbContext.Lessons
        .Select(l => new
        {
            dto = new LessonDto(l.Id, ... other),
            full = l
        })
        .Select(row => row.full is ArticleLesson
        ? new ArticleLessonDto(row.dto)
        {
            Content = (row.full as ArticleLesson).Content,
        }
        : row.full is VideoLesson
        ? new VideoLessonDto(row.dto)
        {
            VideoUrl = (row.full as VideoLesson).VideoUrl,
        }
        : (LessonDto)null
    )
    .ToList();

最新更新