从可选的导航属性中仅选择特定字段

时间:2019-05-09 23:59:11

标签: c# .net entity-framework entity-framework-core

我有两个实体-UserPlan

class Plan
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string FieldA { get; set; }
    public string FieldB { get; set; }
    ...
}

class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int PlanId { get; set; }
    public Plan Plan { get; set; }
}

我想选择一个特定的用户并填充其Plan属性,但只能使用特定的字段(IdName)。 我知道这应该很简单,我只需要写

db.Users
  .Select(u => new User()
  {
      Id = u.Id,
      Name = u.Name,
      PlanId = u.PlanId,
      Plan = new Plan()
      {
          Id = u.Plan.Id,
          Name = u.Plan.Name
      }
  })
  .SingleOrDefault(u => u.Id == 1);

棘手的部分是Plan是可选的(不是说PlanId可以为null,而是说PlanId可以指向不存在的Plan对象)。

Plan存在时,一切都会按预期运行,但是当它不存在时,Plan属性仍将填充,其中包含一个Id但具有一个空Name

示例:

{
    "Id": 1,
    "Name": "some name..",
    "PlanId": 9, // There is no Plan object with Id = 9
    "Plan": {
        "Id": 9,
        "Name": null
    }
}

我期望Plan为空。 我该如何实现?

谢谢

2 个答案:

答案 0 :(得分:0)

为什么不仅仅为填充Plan字段设置条件?

db.Users
.Select(u => new User()
{
    Id = u.Id,
    Name = u.Name,
    PlanId = u.PlanId,
    Plan = u.Plan.Name == null ? null : new Plan()
    {
        Id = u.Plan.Id,
        Name = u.Plan.Name
    }
})
.SingleOrDefault(u => u.Id == 1);

在评论讨论之后,另一种方法是:

db.Users
.Select(u => new User()
{
    Id = u.Id,
    Name = u.Name,
    PlanId = u.PlanId,
    Plan = db.Plans.Find(u.PlanId)
})
.SingleOrDefault(u => u.Id == 1);

Find应该返回null(如果在当前上下文或存储中未找到带有Plan的{​​{1}})

答案 1 :(得分:0)

像这样使用GroupJoin

var userPlanPair = db.Users
  .GroupJoin(db.Plans, u => u.PlanId, p => p.Id, (user, plans) => new { user, plans })
  .SelectMany(pair => pair.plans.DefaultIfEmpty(), (pair, plan) => new { pair.user, plan = plan != null ? new Plan() { Id = plan.Id, Name = plan.Name } : null })
  .SingleOrDefault(pair => pair.user.Id == 1);

GroupJoinSelectManyDefaultIfEmpty的组合转换为SQL形式的左连接。

resultSelector的{​​{1}}中,您需要从SelectMany中查询特定字段。

要获得最终结果-具有Plan属性的User对象,只需从用户对中选择并计划。

Plan