C# 搜索元组的LINQ查询

C# 搜索元组的LINQ查询,c#,linq,C#,Linq,我有一个元组列表(list)的Fname和Version作为输入 例如 是否可以编写一个LINQ查询,它基本上执行以下SQL查询的操作,并返回Name和AttribX的元组 SELECT e.Name, a.AttribX FROM Element e JOIN Attributes a ON a.AId=e.EAId where (a.FName='firstname1' and a.Version='1.0.1') OR (a.Fname='firstname2' and a.Vers

我有一个元组列表(
list
)的
Fname
Version
作为输入

例如

是否可以编写一个LINQ查询,它基本上执行以下SQL查询的操作,并返回
Name
AttribX
的元组

SELECT e.Name, a.AttribX
FROM Element e
JOIN Attributes a ON a.AId=e.EAId
where (a.FName='firstname1' and a.Version='1.0.1')
   OR (a.Fname='firstname2' and a.Version='2.3.3')
   OR (a.Fname='firstname3' and a.Version='4.4.1')

输入中大约有1000个元组。

您的
Where
子句可以是(如果使用LINQ to对象):


第二个代码示例只是将这两个字段连接起来——这将对数据库查找产生负面影响(因为它可能需要进行扫描而不是查找)。例如,如果
FirstName
LastName
包含
-
,也可能会出现问题。从正面来看,它将只使用1000个参数,而不是2000个。:)

如果要生成SQL,可以通过构建
where
子句来避免字符串连接:

Expression<Func<Attributes, bool>> inTuples = a => false;
inTuples = yourListOfTuples.Aggregate(inTuples, (predicate, tuple) => predicate
    .Or(a => a.FName == tuple.Item1 && a.Version == tuple.Item2));
要将结果转换为元组列表,您可能需要进行一些欺骗:

var resultingTuples = filteredQuery
    .Select(a => new {a.Name, a.AttribX})
    .AsEnumerable()
    .Select(a => (a.FName, a.AttribX))
    .ToList();

(请注意,我返回了
a.FName
而不是
e.Name
,以保持示例的简单。)

101 Linq示例页面是一个很好的起点。Linq支持连接两个列表,因此有一些示例:您想使用元组作为实际SQL Linq查询的过滤器吗?是的,这是一个包含1000个元组的实体框架,您正在从中构建一个地狱般的SQL查询,您确定没有其他选项吗?@Chris you建议,现在这意味着有人会用它来回答问题并获得选票!如果源代码是实体框架数据库集,这将不起作用!如果源数据(即,
yourData
)是实体框架等,那么这将不起作用。看。@DavidG OP明确表示他/她有一份tuples@Esko是的,作为输入,但没有明确说明源是什么。我怀疑元组实际上是DbSet查询的过滤器。例如,<代码> ATTIRBX <代码>来自何处?然后考虑将它们添加到数据库中,避免使用元组。它们很少有好的用例(除了较新的C#7版本)。我在
中遇到了一个错误
No重载for method'或'takes 1 arguments
。(inTuples,(谓词,元组)=>谓词。或…
有什么想法吗?啊,从我需要为链接或链接中描述的构建函数扩展中找到了答案。感谢您的响应。我为我的答案增加了清晰度。它编译得很好,但当我试着运行它时,我得到了错误
二进制运算符,或者没有为类型的System.Func'2定义[MainDB.tblOrder,System.Boolean]'和'System.Func'2[MainDB.tblOrder,System.Boolean]'。“}
在Or语句中。我最终使用了PredicateBuilder,这是我从中获得的。它与您的答案非常相似。我喜欢您的答案,但不明白为什么它不起作用:(
var tuples = yourListOfTuples.Select(z => z.Item1 + "-" + z.Item2).ToList();
var results = yourData.Where(z => tuples.Contains(z.FirstName + "-" + z.Version))
Expression<Func<Attributes, bool>> inTuples = a => false;
inTuples = yourListOfTuples.Aggregate(inTuples, (predicate, tuple) => predicate
    .Or(a => a.FName == tuple.Item1 && a.Version == tuple.Item2));
var filteredQuery = attributesQuery.Where(inTuples).AsEnumerable();
var resultingTuples = filteredQuery
    .Select(a => new {a.Name, a.AttribX})
    .AsEnumerable()
    .Select(a => (a.FName, a.AttribX))
    .ToList();