如果存储库不应该返回DTO,我如何返回具有子实体数量的实体?

时间:2015-07-17 12:35:05

标签: c# entity-framework data-access-layer dto

我读过存储库不应该返回DTO而是实体。那么如何返回具有子实体数量的实体列表呢?

这是我在数据库中的实体:

public IEnumerable<Note> GetNotes()
{
    return context.Notes.OrderBy(x => x.Title).ToList();
}

现在我有了存储库:

public class NoteWithCommentsCountDTO
{
    public Note Note { get; set; }
    public int NoteCommentsCount { get; set; }
}

public IEnumerable<NoteWithCommentsCountDTO> GetNotesWithNoSpamCommentsCount()
{
    IEnumerable<NoteWithCommentsCountDTO> notesDTO = _notesRepository.GetNotes()
        .Select(x =>
        new NoteWithCommentsCountDTO
        {
            Note = x,
            NoteCommentsCount = x.Comments.Where(y => y.IsSpam == false).Count()
        });

    return notesDTO;
}

并在服务中:

public IEnumerable<NoteWithCommentsCountDTO> GetNotesWithNoSpamCommentsCount()
{
    IQueryable<NoteWithCommentsCountDTO> notesDTO = context.Notes
        .Include(x => x.Comments)
        .OrderBy(x => x.Title)
        .Select(x =>
        new NoteWithCommentsCountDTO
        {
            Note = x,
            NoteCommentsCount = x.Comments.Where(y => y.IsSpam == false).Count() 
        }).ToList();

    return notesDTO;
}

不幸的实体框架会生成与笔记数量一样多的SQL查询。

如果我在存储库中使用DTO,我可以消除这个问题:

<TextView
   android:id="@+id/tv_ld_header"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:text="Hello"
   android:layout_gravity="center"
   android:textColor="#fff"
   android:textSize="@dimen/textSize"
   android:textStyle="bold" />`

现在,Entity Framework生成一个SQL查询但我从存储库返回DTO,而不是实体 - 解决方案是什么?

2 个答案:

答案 0 :(得分:0)

您可以在数据层中使用IncludeComments预取Note

public IEnumerable<Note> GetNotes()
{
    return context.Notes.OrderBy(x => x.Title).Include(x => x.Comments).ToList();
}

功能参考:https://msdn.microsoft.com/en-us/library/system.data.entity.dbextensions.include(v=vs.103).aspx

答案 1 :(得分:0)

您不能对实体这样做。实体应与表格完全等效。

你有2个解决方案
1.您可以使用DTO,如您的示例所示 要么
2.你使用动态类型(它与DTO相同,但你实际上不必创建类)。 类似的东西:

public dynamic GetNotesWithNoSpamCommentsCount()
{
    var notesDTO = _notesRepository.GetNotes()
        .Select(x =>
        new 
        {
            Note = x,
            NoteCommentsCount = x.Comments.Where(y => y.IsSpam == false).Count()
        });

    return notesDTO;
}

在我看来,选项1是最佳解决方案,特别是如果您正在开发n层应用程序(有关如何将实体映射到业务逻辑检查this so post的详细信息)。