如何使用LINQ获取一个集合中存在的整数列表,而不是另一个不同类型的整数列表?

时间:2009-10-02 19:41:28

标签: c# .net linq

我有两个不同的集合:

List<int>
IEnumerable<IDataRecord>

第一个包含主键列表。第二个包含数据记录。我想要做的是根据给定的列名确定第一个集合中哪些主键不存在,并将它们作为新集合返回。

例如,如果我有这个:

private List<int> _currentKeys = new List<int>();

public void Update(DbDataReader reader, string keyColumn) {
    var records = reader.AsEnumerable(); // my own extension method
    var difference = // LINQ stuff here
}

Say _currentKeys包含[1,2,3,4,5],reader包含名为ID的列中值为[1,4,5]的记录。如果我调用Update,我需要获得一个包含[2,3]的集合。

与往常一样,我觉得这很简单,但两个系列不同类型的事实完全让我失望。结合我还没有使用过LINQ的事实。

4 个答案:

答案 0 :(得分:3)

诀窍是在主键列表中查询您的阅读器不包含的键。 where语句指定要比较的阅读器中的哪一列。但是,它们必须具有相同的数据类型。

List<int> _currentKeys = new List() { 1, 2, 3, 4, 5);

List<int> NotFound = (
    from pk in _currentKeys
    where !reader.Select(rec => rec.MyFieldToCompare).Contains(pk)
    select pk).ToList();

如果它们的数据类型不同,只需转换内存集合以匹配数据库集合的类型。 IE如果您的主键在数据库中保存为varchar,您可以像这样隐藏_currentKeys:

List<string> _currentKeysStr = 
    Array.ConvertAll<int, string>
        (_currentKeys.ToArray(), Convert.ToString).ToList();

答案 1 :(得分:0)

你可以这样做:

var difference = _currentKeys.Where(k => !records.Any(r => (int)r[keyColumn] == k));

我假设keyColumn标识的列可以强制转换为int。

答案 2 :(得分:0)

我过去采用的方法是:

IEnumerable<int> exceptions = _currentKeys.ToArray().Except(reader.Select(x => x.ID).ToArray());

你有一点投射,我不是百分百肯定是必要的,但我没有看到我的需求的重大表现。

答案 3 :(得分:0)

将Records集合的值投影到Int列表中并使用except函数(返回一个集合中不在另一个集合中的值)

var difference = _currentKeys.Except(records.Select(r=>r.ID)