我有两个实体-User
和Plan
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
属性,但只能使用特定的字段(Id
和Name
)。
我知道这应该很简单,我只需要写
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
为空。
我该如何实现?
谢谢
答案 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);
GroupJoin
,SelectMany
和DefaultIfEmpty
的组合转换为SQL形式的左连接。
在resultSelector
的{{1}}中,您需要从SelectMany
中查询特定字段。
要获得最终结果-具有Plan
属性的User
对象,只需从用户对中选择并计划。
Plan