我有三个类定义如下:
public class MaterialByOperator
{
public int IdOperator{ get; set; }
public int IdMaterial { get; set;}
}
public class Material
{
public int Id { get; set; }
public string Name { get; set; }
}
public class AssignedOperator
{
public int idOperation { get; set; }
public int idOperator { get; set; }
}
IdMaterial
中的 MaterialByOperator
是Material
的“ForeignKey”。关系是One to Many
。
IdOperator
中的{p> MaterialByOperator
是AssignedOperator
关系中One to One
的“ForeignKey”。
然后我定义了这个3 ObservableCollection
:
public ObservableCollection<Material> Materials;
public ObservableCollection<MaterialByOperator> MaterialsXOperator;
public ObservableCollection<AssignedOperator> AssignedOperators;
我想要的是获得没有任何材料的运营商名称。我现在这样做:
var mate = MaterialsXOperator.GroupBy(x => x.idOperator); //Group materials by operatorId
//left join assignedOperators with the grouped materials
var opeasigmate = AssignedOperators.GroupJoin(mate, oper => oper.idOperator,
grupo => grupo.Key, (oper, grupo) => new { oper, grupo });
var operWithoutmate = opeasigmate.Where(x => x.grupo.Count() == 0);
我想知道的是,因为我的LINQ知识不是很广泛(不管你信不信,我多年来一直禁止我的工作)是否有任何最简单的方法来实现我想要的东西?正如我所说,我的解决方案有效,但我希望看到其他观点,希望顺便学习。
答案 0 :(得分:2)
使用Any
肯定更简单:
var operWithoutmate = AssignedOperators
.Where(ao => !MaterialsXOperator.Any(mo => mo.IdOperator == ao.idOperator);
但一般使用join
效率更高,所以我建议你保持这种方式。唯一的改进可能是将x.grupo.Count() == 0
替换为!x.grupo.Any()
。此外,GroupBy
在这种情况下也是多余的,因此查询可以是:
var operWithoutmate = AssignedOperators
.GroupJoin(MaterialsXOperator, ao => ao.idOperator, mo => mo.IdOperator,
(ao, moGroup) => new { ao, moGroup })
.Where(r => !r.moGroup.Any())
.Select(r => r.ao);
我个人觉得当涉及联接时,查询语法更容易,更易读:
var operWithoutmate =
from ao in AssignedOperators
join mo in MaterialsXOperator on ao.idOperator equals mo.IdOperator into moGroup
where !moGroup.Any()
select ao;