【问题标题】:If repository shouldn't return DTO, how can I return entities with number of children entities?如果存储库不应返回 DTO,我如何返回具有多个子实体的实体?
【发布时间】:2015-10-07 04:25:47
【问题描述】:

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

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

public class Note
{
    [Key] 
    public int NoteId { get; set; }

    [Required]
    public string Content { get; set; }

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

现在我在存储库中:

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;
}

不幸的是,Entity Framework 生成的 SQL 查询与注释的数量一样多。

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

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,而不是实体 - 解决方案是什么?

【问题讨论】:

  • 从存储库返回 DTO。这是完全可以接受的。

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


【解决方案1】:

您不能对实体执行此操作。实体应该完全等同于表。

您有 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)。

【讨论】:

    【解决方案2】:

    您可以在数据层使用Include 为每个Note 预取Comments

    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

    【讨论】:

    • 但我只需要 cmets 的数量,而不是所有 cmets
    猜你喜欢
    • 2021-04-20
    • 2016-02-01
    • 1970-01-01
    • 2016-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-06
    相关资源
    最近更新 更多