使用List <tuple <int,int =“”>&gt;在Linq中返回数据

时间:2016-05-25 14:22:53

标签: c# linq

假设:

List<int> myList;

如果我想返回此列表中包含记录ID的数据,我只会这样做:

var q = db.Table.Where(c=> myList.Contains(c.ID));

然而,鉴于:

List<Tuple<int, int>> myList;

如何编写Linq查询以返回满足两个条件的记录?有一个数据点我会写:

var q = db.Table.Where(c=>
            c.ID == myList.Item1
            && c.AnotherValue == myList.Item2);

如何将上述语句转换为List<Tuple<int, int>>

5 个答案:

答案 0 :(得分:6)

Tuple是一个无法由Linq Provider转换为sql的结构。解决方案可能是切换到Linq to Objects

var q = db.Table.AsEnumerable()
                .Where(c=> myList.Any(tuple => c.ID == tuple.Item1 &&
                                           c.AnotherValue == tuple.Item2));

但是这个解决方案的坏处是你要从该表加载所有行来过滤内存。

另一种解决方案可能是使用Linqkit

var predicate = PredicateBuilder.False<Table>();

foreach (string t in myList)
{
    predicate = predicate.Or(c =>c.ID == t.Item1 && c.AnotherValue == t.Item2));
}

db.Table.AsExpandable().Where(predicate);

您可以在此link

中找到有关此最后一个解决方案的更多信息

答案 1 :(得分:1)

var q = db.Table.AsEnumerable().Where(c => myList.Any(tuple => c.ID == tuple.Item1 &&
                                               c.AnotherValue == tuple.Item2));

使用Any,您可以检查myList中是否至少有一个元素符合您的条件。

但正如@octaviocci指出的那样,这不能转换为SQL,因此您需要先调用AsEnumerable()并在本地进行过滤,如果存在大量不相关的记录,这可能不是您想要的

答案 2 :(得分:0)

以下是一些示例代码,说明了一种方法:

DataTable dt = new DataTable("demo");
// hydrate your table here...

List<Tuple<int, int>> matches = new List<Tuple<int, int>>();

Func<List<Tuple<int,int>>, DataRow, bool> RowMatches = (items, row) => {

        var rowValue1 = (int)row["Id"];
        var rowValue2 = (int)row["SomeOtherValue"];

        return items.Any(item => item.Item1 == rowValue1 && item.Item2 == rowValue2);
    };

var results = dt.Rows.Cast<DataRow>().Where(r => RowMatches(matches, r));
Console.WriteLine(results.Any());

答案 3 :(得分:0)

见下面的代码:

List<Tuple<int, int>> myList;

var set = new HashSet(myList);

var q = db.Table.AsEnumerable().Where(c=> set.Contains(new Tuple(c.ID, c.AnotherValue)));

请注意,哈希集用于优化大Where的{​​{1}}子句的执行。

答案 4 :(得分:0)

由于Tuple无法使用Linq to Entities,您可以尝试这样的事情:

List<int> items1 = myList.Select(t => t.Item1).ToList();
List<int> items2 = myList.Select(t => t.Item2).ToList();

var q = db.Table.GroupBy(m => { m.ID, m.AnotherValue })
                .Where(g => items1.Contains(g.Key.ID) && 
                            items2.Contains(g.Key.AnotherValue))
                .SelectMany(g => g);