按对象属性从列表中排除项目

时间:2012-03-30 13:50:04

标签: c# linq entity-framework

我正在尝试根据它们在列表中的存在来构建项目列表。

  • itemsAll包含所有产品
  • itemsNew仅包含新产品
  • 我希望itemsOld只包含旧产品(即itemsAll - itemsNew

这是我的方法,它没有返回正确数量的项目。

var itemsAll = objProductStagingRepository.AllImports(fileId, cid).ToList();

var itemsNew = objProductStagingRepository.DetectNonPresentProductNames(fileId, cid).ToList();

var itemsOld = from t1 in itemsAll where !(from o in itemsNew select o.Id).Contains(t1.Id)
                                        select t1; // this does not work

有没有人对我如何解决这个问题有任何建议?我尝试了itemsAll.Except(itemsNew),但也没有产生正确的结果!

4 个答案:

答案 0 :(得分:1)

我认为你可能会使用Except方法,但你需要为方法提供一个相等比较器,以便知道两个项目何时相等。

http://msdn.microsoft.com/en-us/library/bb336390.aspx

在您的问题中,您似乎没有使用自己的比较器,所以它正在比较项目以查看它们是否是内存中的同一对象(最有可能),这是您的内容我正试图这样做。

您希望按数据库标识比较对象,这意味着您需要提供自己的比较器。

示例:

public class Item
{
    public int Id { get; set; }
}

class ItemComparer : IEqualityComparer<Item>
{
    public bool Equals(Item x, Item y)
    {    
        if (Object.ReferenceEquals(x, y)) return true;

        if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
            return false;

        return x.Id == y.Id;
    }

    public int GetHashCode(Item value)
    {
        if (Object.ReferenceEquals(value, null)) return 0;

        int hash = value.Id.GetHashCode();

        return hash;
    }

}

答案 1 :(得分:1)

itemsOld.AddRange(itemsAll.Where(p => !itemsNew.Any(a => a.Id == p.Id)));

答案 2 :(得分:1)

我更喜欢流利语法所以:

var itemsOld = itemsAll.Where(x => !itemsNew.Any(y => y.Id == x.Id));

var itemsOld = itemsAll.Where(x => !itemsNew.Exists(y => y.Id == x.Id));

答案 3 :(得分:0)

这可能有效

var itemsOld = from a in itemsAll
               join n in itemsNew on a.Id equals n.Id into ng
               where !ng.Any()
               select a;