C# LINQ选择包含字符串的所有子集合的所有项
我使用jqueryui自动完成来帮助用户选择项目。我无法从对象的子集合中选择正确的项。C# LINQ选择包含字符串的所有子集合的所有项,c#,linq,C#,Linq,我使用jqueryui自动完成来帮助用户选择项目。我无法从对象的子集合中选择正确的项。 对象结构(简化)为 公共类TargetType { 公共int Id{get;set;} 公共字符串名称{get;set;} 公共虚拟ICollection子类别{get;set;} 公共目标类型() { 子类别=新HashSet(); } } 公共类子类别 { 公共int Id{get;set;} 公共字符串名称{get;set;} 公共虚拟ICollection子目标类型{get;set;} 公共子类别(
对象结构(简化)为
公共类TargetType
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共虚拟ICollection子类别{get;set;}
公共目标类型()
{
子类别=新HashSet();
}
}
公共类子类别
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共虚拟ICollection子目标类型{get;set;}
公共子类别()
{
SubTargetTypes=新HashSet();
}
}
目前我正在使用嵌套的foreach循环来实现这一点,但是有更好的方法吗?当前代码:
List<SubTargetResponse> result = new List<SubTargetResponse>();
foreach (SubCategory sc in myTargetType.SubCategories)
{
foreach (SubTargetType stt in sc.SubTargetTypes)
{
if (stt.Name.ToLower().Contains(type.ToLower()))
{
result.Add(new SubTargetResponse {
Id = stt.Id,
CategoryId = sc.Id,
Name = stt.Name });
}
}
}
列表结果=新列表();
foreach(myTargetType.SubCategories中的子类别sc)
{
foreach(sc.子目标类型中的子目标类型stt)
{
if(stt.Name.ToLower().Contains(type.ToLower()))
{
结果。添加(新的子目标响应{
Id=stt.Id,
CategoryId=sc.Id,
Name=stt.Name});
}
}
}
您可以像这样使用Linq
var result = myTargetType.SubCategories
.SelectMany(sc => sc.SubTargetTypes)
.Where(stt => stt.Name.ToLower().Contains(type.ToLower()))
.Select(stt => new SubTargetResponse {
Id = stt.Id,
CategoryId = sc.Id,
Name = stt.Name });
上面的查询不起作用。以下内容应该可以,但我不建议这样做,因为这样做不会更快或更具可读性
var result = myTargetType.SubCategories
.Select(sc => new Tuple<int, IEnumerable<SubTargetType>>
(sc.Id,
sc.SubTargetTypes.Where(stt => stt.Name.ToLower().Contains(type.ToLower()))))
.SelectMany(tpl => tpl.Item2.Select(stt => new SubTargetResponse {
Id = stt.Id,
CategoryId = tpl.Item1,
Name = stt.Name }));
var result=myTargetType.SubCategories
.选择(sc=>新元组
(理学士),
sc.SubTargetTypes.Where(stt=>stt.Name.ToLower().Contains(type.ToLower()))
.SelectMany(tpl=>tpl.Item2.Select(stt=>newsubtargetresponse{
Id=stt.Id,
类别ID=第三方物流项目1,
Name=stt.Name});
实际上有两个不同的问题
LINQ选择包含字符串的所有子集合的所有项
解决方案:
(A) LINQ语法:
var result =
(from sc in myTargetType.SubCategories
from stt in sc.SubTargetTypes.Where(t => t.Name.ToLower().Contains(type.ToLower()))
select new SubTargetResponse
{
Id = stt.Id,
CategoryId = sc.Id,
Name = stt.Name
})
.ToList();
(B) 方法语法:
var result =
myTargetType.SubCategories.SelectMany(
sc => sc.SubTargetTypes.Where(stt => stt.Name.ToLower().Contains(type.ToLower())),
(sc, stt) => new SubTargetResponse
{
Id = stt.Id,
CategoryId = sc.Id,
Name = stt.Name
})
.ToList();
目前我使用嵌套的foreach循环来实现这一点,但是有更好的方法吗
嗯,这取决于你所说的“更好”是什么意思。将您的代码与LINQ解决方案进行比较并回答问题。我个人并不认为LINQ在这种情况下更好(除了没有大括号和不同的缩进,但有很多隐藏的垃圾),以及如何看待中的第二个LINQ版本-如果这比您的代码“更好”,我不知道我们要去哪里
type
从何而来?它只是一个包含搜索参数的字符串。这不会编译。在第CategoryId=sc.Id行,
error“sc在当前上下文中不存在”抱歉,我忽略了这一点!我已经更新了答案,但正如我所提到的,我可能不建议这样做。所以还是坚持使用嵌套循环更好吗?我会说,是的。首先,如果正确写入非Linq代码(with for、if else等),则大多数情况下使用Linq不会获得性能提升。因为Linq方法在内部也会做同样的事情。Linq
的巨大好处是代码紧凑,可读性增强。在这里,它也不提供。反而降低了性能(newtuple()
part)。@Sami我们也可以对multipleToList().ForEach()进行同样的操作。不过,这也没什么好处。如果你还没有用“更好的方式”阅读本文,我指的是更可读和/或更好的性能。第一个答案让我确信没有,我应该坚持循环。@Sami,我明白了。所以您看到,在本例中,LINQ既不更具可读性,也不更具性能。后者几乎总是正确的:-)而且对于可读性来说,LINQ通常更好,但在这里不是这样,而公认答案中的第二个(有效)变体简直是荒谬可笑。正确的端口(我的(A)版)与环路基本相同。所以,是的,继续循环:-)
var result =
myTargetType.SubCategories.SelectMany(
sc => sc.SubTargetTypes.Where(stt => stt.Name.ToLower().Contains(type.ToLower())),
(sc, stt) => new SubTargetResponse
{
Id = stt.Id,
CategoryId = sc.Id,
Name = stt.Name
})
.ToList();