将“AND”应用于两个列表之间的所有项目

时间:2012-12-19 10:24:32

标签: c# linq

我有两个不同类型的集合:

// First Collection
public class ObjectA
{
   public IEnumerable<SomeObject> Persons { get; set; }
   public IEnumerable<SomeOtherObject> Items { get; set; }
}

public class SomeObject
{
   public string ID { get; set; }
}
public class SomeOtherObject
{
   public string ID { get; set; }
}

// Second Collection (ID property holds unique values, PersonID and EntityID do not)
public class ObjectB
{
    public string ID { get; set; }
    public string PersonID { get; set; }
    public string EntityID{ get; set; }
}

// Assuming the following entries...
var list1 = new ObjectA();
var persons = new List<SomeObject>();
persons.Add(new SomeObject() { ID = "A" });
persons.Add(new SomeObject() { ID = "B" });
persons.Add(new SomeObject() { ID = "C" });
list1.Persons = persons;

var items = new List<SomeOtherObject>();
items.Add(new SomeOtherObject() { ID = "1" });
items.Add(new SomeOtherObject() { ID = "2" });
list1.Items = items;

var list2 = new List<ObjectB>();
list2.Add(new ObjectB() { ID = "1", PersonID = "C", EntityID = "1" });
list2.Add(new ObjectB() { ID = "2", PersonID = "A", EntityID = "1" });
list2.Add(new ObjectB() { ID = "3", PersonID = "A", EntityID = "2" });
list2.Add(new ObjectB() { ID = "4", PersonID = "B", EntityID = "1" });
list2.Add(new ObjectB() { ID = "5", PersonID = "B", EntityID = "2" });

给出这两个列表(list1和list2)。如何在list2中找到项目 PersonID = A和B. 和 EntityID = 1 AND 2

换句话说,必须满足所有条件,因此'人C'不会成功,因为他们只有EntityID =“1”,而不是“1”和“2”

6 个答案:

答案 0 :(得分:1)

你可以使用这样的东西

list2.Where(b => list1.Persons.Exists(person => person.ID == b.PersonID) &&
                 list1.Items.TrueForAll(id => list2.Exists(bs => bs.EntityID == id.ID && bs.PersonID == b.PersonID)))

这将从list2中提供4个项目(如果需要,您可以选择独特的人员)

答案 1 :(得分:1)

如果我正确地阅读了这个问题,这个查询将为您提供包含list1.Items中列出的所有EntityIds的所有人员ID(而不是硬编码1&amp; 2)

var validIds = list1.Items.Select(i => i.ID);
var validPersonIds = list2.GroupBy(p => p.PersonID)
                          .Where(g => validIds.All(i => g.Any(x => x.EntityID == i)))
                          .Select(g => g.Key);

更新:根据您的评论,我认为这就是您的需求。它返回list2中具有ID 2,3,4和5的对象

var validEntityIds = list1.Items.Select(i => i.ID);
var validPersonIds = list1.Persons.Select(i => i.ID);
var validObjects = list2.GroupBy(p => p.PersonID)
                        .Where(g => validPersonIds.Contains(g.Key) &&
                                    validEntityIds.All(i => g.Any(x => x.EntityID == i)))
                        .SelectMany(g => g);

答案 2 :(得分:0)

试试这个:这可以为您提供所需的组合。

        var listSelected = (from val2 in list2
                            where val2.PersonID == "A" || val2.PersonID == "B"
                            && val2.EntityID == "1" || val2.EntityID == "2"
                            select val2).ToList();

答案 3 :(得分:0)

也许这会产生你想要的东西:

  var result1 = list2.Where(row=> row.EntityID=="1").Select(r=>r.PersonID);
  var result2 = list2.Where(row => row.EntityID == "2").Select(r => r.PersonID);
  var finalResult = result1.Intersect(result2);

答案 4 :(得分:0)

您可以尝试以下内容:

list2.Where(p => p.EntityID == "1" || p.EntityID == "2")
    .GroupBy(p => p.PersonID)
    .Where(grp => grp.Count() == 2);

这将返回指定了实体1和2的list2中的每个人;所以示例数据中的“A”和“B”。

修改

根据您对Azhar的评论,以下内容更为通用:

var entityFilter = new string[]{"1", "2"};

list2.Where(p => entityFilter.Contains(p.EntityID))
    .GroupBy(p => p.PersonID)
    .Where(grp => grp.Count() == entityFilter.Count());

答案 5 :(得分:0)

var query = list2.GroupBy(item => item.PersonID)
                 .Where(g => g.Any(item => item.EntityID == "1") &&
                             g.Any(item => item.EntityID == "2"))
                 .SelectMany(g => g);

返回除第一项之外的所有项目,因为没有PersonID等于C且EntityID等于1和2的项目。