如何从DB获取实体,包括导航属性和子列表总量

时间:2017-08-16 19:57:16

标签: entity-framework linq

我有下一个实体

public class Objective
{
    public virtual UserInfo AssignedUser { get; set; }
    public int? AssignedUserID { get; set; }
    public string ObjectiveText { get; set; }
    public virtual ICollection<ObjectiveTask> Tasks { get; set; }
    public virtual UserInfo User { get; set; }
    public int UserID { get; set; }
}

一个目标可能有一个分配用户和一个用户但很多任务。

从DB获取实体后,我将其映射到DTO类,看起来像这样

public class ObjectiveListViewModel
{
    public string AssignedString { get; set; }
    public string ObjectiveText { get; set; }
    public int TasksCount { get; set; }
    public string UserContactName { get; set; }
}

映射设置不计量

当我使用此类查询执行此操作时

(from objective in context.Set<Objective>() select objective)
.Include(o => o.User)
.Include(o => o.AssignedUser)
.ToListAsync();

一切都很酷 - 加载了用户和分配的用户属性,无需对DB进行额外查询即可获取数据。

但是我需要返回具有任务数量的目标。 为此,我创建了一个通用类

public class EntitySubCount<TEntity>
{
    public TEntity Entity { get; set; }
    public int GroupCount { get; set; }
} 

以这种方式使用

(from objective in context.Set<Objective>() select objective)
.Include(o => o.User)
.Include(o => o.AssignedUser)
.Select(o=> new EntitySubCount<Objective> { 
    Entity = o, 
    GroupCount = o.Tasks.Count })
.ToListAsync();

但未加载用户和分配的用户属性,并且需要对DB进行额外查询才能获取其数据。 我明白这是因为懒加载。

问题是 - 如何通过加载导航从DB my Entity获取。属性和一次性的任务数量?

感谢您的帮助

1 个答案:

答案 0 :(得分:1)

你很亲密。如果您正在预测,则不需要包含。在这种情况下,我投射到一个匿名类型,但如果需要,您可以创建一个ViewModel类来投影。

var objectiveList = context.Objectives
    .Select(o => new 
    {
        Entity = o,
        // or you could just pick the properties:
        ObjectiveText = o.ObjectiveText,
        User = o.User,
        AssignedUser = o.AssignedUser,
        GroupCount = o.Tasks.Count 
    }).ToList();

编辑:我看到你已经有了ViewModel(DTO)。你可能正在寻找这样的东西:

var objectiveList = context.Objectives
    .Select(o => new ObjectiveListViewModel
    {
        AssignedString = o.AssignedUser.Name,
        ObjectiveText = o.ObjectiveText,
        TasksCount = o.Tasks.Count 
        UserContactName = o.User.Name
    }).ToList();