在EF Core中使用继承时,我正在努力避免重复投影逻辑。
这是我的场景:我有三种类型:
Lesson
(这是一个抽象类((属性:Id
、Title
等(ArticleLesson
(继承自Lesson
((属性:Content
、TotalWoddsCount
等(VideoLesson
(继承自Lesson
((属性:VideoUrl
、Duration
等(
几乎所有事情都由EF Core正确处理,我使用默认的每层次表(TPH(方法。
当我想从数据库中检索课程,并且我需要ArticleLesson
和VideoLesson
之间的一些共享列(即Lesson
的一些属性(,加上ArticleLesson
或VideoLesson
特定的一些属性时,就会出现问题。这是我想出的表达式:
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();
正如您所看到的,我将重复共享属性部分两次。在这个例子中,只有两个属性被重复,Id
和Title
,但在现实世界中,你可以有几十个;并且必须像这样重复所有这些将是一个h.
有没有办法使这种投影表达更简洁,避免重复?
您可以向LessonDto
、ArticleLessonDto
和VideoLessonDto
添加一个接受不同共享属性的构造函数。
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();