Reputation: 5892
I'm trying to build a list of items based on their presence in a list.
itemsAll
contains all products itemsNew
contains only new productsitemsOld
to contain only old products (i.e. itemsAll
-
itemsNew
)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
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
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
Reputation: 14929
itemsOld.AddRange(itemsAll.Where(p => !itemsNew.Any(a => a.Id == p.Id)));
Upvotes: 1
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