LINQ - 3个ObservableCollections的左连接

时间:2016-05-20 08:37:03

标签: c# linq lambda

我有三个类定义如下:

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中的

MaterialByOperatorMaterial的“ForeignKey”。关系是One to Many

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

1 个答案:

答案 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;