Nick
Nick

Reputation: 5892

Excluding items from a list by object property

I'm trying to build a list of items based on their presence in a list.

This was my approach, which doesn't return the correct number of items.

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

Does anybody have any suggestions as to how I shuold be approacing this? I have tried itemsAll.Except(itemsNew) which also doesn't yield the correct results!

Upvotes: 0

Views: 358

Answers (4)

Omar
Omar

Reputation: 16621

I prefer the fluent syntax so:

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

or

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

Upvotes: 1

Joseph
Joseph

Reputation: 25533

I think you probably could use the Except method, but you would need to provide an equality comparer for the method to know when two items are equal.

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

In your question it looks like you're not using your own comparer, so it's comparing the items to see if they are the same object in memory (most likely), which is not what you're trying to do.

You want to compare the objects by database identity, which means you need to provide you're own comparer.

Example:

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

}

Upvotes: 1

daryal
daryal

Reputation: 14929

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

Upvotes: 1

Aducci
Aducci

Reputation: 26694

This might work

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

Upvotes: 0

Related Questions