c# – LINQ – 3个ObservableCollections的左连接

我有三个类定义如下:

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; }
}

MaterialByOperator中的IdMaterial是Material的“ForeignKey”.这种关系是一对多的.

MaterialByOperator中的IdOperator是一对一关系中AssignedOperator的“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知识不是很广泛(不管你信不信,我多年来一直禁止我的工作)是否有任何最简单的方法来实现我想要的东西?正如我所说,我的解决方案有效,但我希望看到其他观点,希望顺便学习.

最佳答案 使用Any绝对更简单:

var operWithoutmate = AssignedOperators
    .Where(ao => !MaterialsXOperator.Any(mo => mo.IdOperator == ao.idOperator);

但是通常使用join更有效,所以我建议你保持这种方式.唯一的改进可能是用.x.grupo.Any()替换x.grupo.Count()== 0.在这种情况下,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;
点赞