Setup
- I have two
List<T>'s. - The data is un-normalized and from different sources which explains the convolution in the desired logic
- An informal compound key in the data is fieldA, fieldB, fieldC.
- The "fields" are strings - reference types - so their values could be null. I want to drop records where they may be matching on null. I get that null references in C# will match, but in SQL they do not. Adding a
!string.IsNullOrEmpty()is easy enough. - This is not a question about DB design or relational algebra.
- I have other logic which covers other criteria. Do not suggest reducing the logic shown such that it might broaden the result set. See # 5 above.
The Problem
I want to find the records in listA that are not in listB based on the informal key. I then want to further refine the listA results based on a partial key match.
The SQL version of the problem:
select
listA.fieldA, listA.fieldB, matching.fieldC
from listA
left join listB keyList on
listA.fieldA = keyList.fieldA and
listA.fieldB = keyList.fieldB and
listA.fieldC = keyList.fieldC
inner join listB matching on
listA.fieldA = matching.fieldA and
listA.fieldB = matching.fieldB
where
keyList.fieldA is null
SQL to LINQ ( Case 7 - Filter data by using IN and NOT IN clause)
Note: IN and NOT IN use the same function in the LINQ query, but it just use a ! (not) symbol for it. Here is the graphical representation:
You use, where <list>.Contains( <item> )
var myProducts = from p in db.Products
where productList.Contains(p.ProductID)
select p;
Or you can have a list predefined as such:
var ids = {1, 2, 3};
var query = from item in context.items
where ids.Contains( item.id )
select item;
For the 'NOT' case, just add the '!' operator before the 'Contains' statement.
来源:https://stackoverflow.com/questions/10885218/implement-not-in-aka-not-exists-logic-in-linq