如何解决使用Linq尝试提取具有相应票证的类别列表
我正在尝试使用Linq Lambda表达式为特定的userId提取具有相应票证的类别列表。
类别:
public class Category
{
public int Id { get; set; }
public string CategoryName { get; set; }
public ICollection<Ticket> Tickets { get; set; }
}
门票:
public class Ticket
{
public int Id { get; set; }
public string Title { get; set; }
public User User { get; set; }
public Category Category { get; set; }
}
用户
public class User
{
public string Id { get; set; }
public string UserName { get; set; }
public ICollection<Ticket> Tickets { get; set; }
}
这是我到目前为止尝试过的。但这还差得远。
public async Task<IEnumerable<Category>> GetCategories(string userid)
{
var categories = _context.Categories
.Include(c => c.Tickets)
.AsQueryable();
categories = categories
.Where(c => c.Tickets.Any(t =>t.User.Id.Equals(id)));
return await categories.ToListAsync();
}
如何获得带有特定用户ID的票证的类别列表?
解决方法
问题是这行代码:
categories = categories.Where(c => c.Tickets.Any(t =>t.User.Id.Equals(id)));
这将返回包含至少1张具有指定用户ID的票证的所有类别,但是将包含该类别中的 all 票证。我的理解是,您只想保留属于指定用户ID的票证。
您的Ticket
由ICollection<Ticket>
而不是IEnumberable<Ticket>
表示的事实使这一点变得更加困难-因为LINQ适用于IEnumerable
。这就是进行ToList()
调用的原因,该调用导致枚举-在这里要注意一点-Ticket
的集合在这一点上不再懒惰。
此代码将执行您想要的操作:
IEnumerable<Category> selection = (from c in categories
select new Category
{
Id = c.Id,CategoryName = c.CategoryName,Tickets = (from t in c.Tickets
where t.User.Id.Equals(id)
select t).ToList()
}).Where(c => c.Tickets.Count() > 0);
但是,我认为,从性能和可读性角度来看,您可能都希望使用循环:
List<Category> selection = new List<Category>();
foreach (var category in categories)
{
category.Tickets = category.Tickets.Where(t => t.User.Id.Equals(id)).ToList();
if (category.Tickets.Count > 0)
{
selection.Add(category);
}
}
最后,由于您的Ticket
类仍然携带Category
信息,因此可能值得使用SelectMany
来简化列表:
var selection = categories.SelectMany(c => c.Tickets.Where(t => t.User.Id.Equals(id)));
这将返回Ticket
s的扁平化列表-但仅返回与所有类别中的指定用户ID匹配的列表。这样做的优点是保持懒惰(仍然是IEnumerable
),比较简单,并且很可能比其他选项具有更高的性能;但是,您不再有嵌套列表。
请选择!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。