假设我的网站中有2个模型/实体,User和Ticket。 用户和票证具有一对多关联(一个用户可以拥有多个票证)。
class User {
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Ticket> Tickets { get; set; }
}
class Ticket {
public int Id { get; set; }
public string Type { get; set; }
}
如您所见,故障单模型不包含对用户模型的任何引用。
我的问题是如何过滤属于特定用户的故障单? 如果Ticket模型引用了User模型,我可以这样做:
IEnumerable<Ticket> tickets = context.Tickets.Where(t => t.User.Id == userId);
但是在Ticket模型中没有User对象,它是不可能的。 我意识到我可以加载我想要的用户然后从其模型中访问其票证,但这将花费我不必要地加载用户,我不想加载用户,我只是想加载它票。
谢谢
更新
让我们说每张票可以有多张子票:
class Ticket {
public int Id { get; set; }
public string Type { get; set; }
public virtual ICollection<Ticket> Children { get; set; }
}
根据用户ID,我想获得属于该用户的所有门票,但不是子门票(没有父门票)。
如果票证模型中没有Parent属性,我怎么能这样做?
即使我在Ticket模型中有一个Parent属性并运行此查询:
var tickets = context.Where(u => u.Id == userId).SelectMany(u => u.Tickets).Where(t => t.Parent == null);
但是根据我的理解,由于延迟加载,Parent属性可以通过在数据库本身实际为null或者仅仅因为它尚未加载而为null ...
答案 0 :(得分:3)
如果你想要的只是特定用户的门票:
var tickets = context.Users
.Where(u => u.Id == userID)
.SelectMany(u => u.Tickets);
假设您的模型是数据库支持的,这将导致单个查询只返回Ticket记录列表。
对于&#34的额外测试;不是其他门票的附加测试&#34;你会添加另一个子句,如下所示:
var tickets = context.Users
.Where(u => u.Id == userID)
.SelectMany(u => u.Tickets)
.Where(t => !context.Tickets.Any(t1 => t1.Children.Contains(t)));
请注意,Any
和All
相似,我只是认为Any
更适合这一点。
答案 1 :(得分:1)
根据更新修改@Corey答案(尝试一下,我只是在没有测试的情况下编写它):
var tickets = context.Users
.Where(u => u.Id == userID)
.SelectMany(u => u.Tickets)
.Where(t => context.Tickets.All(t1 => !t1.Children.Contains(t)));