我有List<Tuple<string,string>>
和Fname
的元组列表(Version
)作为输入。
例如
[('firstname1','1.0.1'), ('firstname2','2.3.3'), ('firstname3','4.4.1')]
是否可以编写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个元组。
答案 0 :(得分:2)
您的Where
子句可能是(如果使用LINQ to Objects):
var results = yourData.Where(z => yourListOfTuples.Contains(new Tuple<string, string>(z.FirstName, z.Version)))
尝试的另一种选择(针对实体框架):
var tuples = yourListOfTuples.Select(z => z.Item1 + "-" + z.Item2).ToList();
var results = yourData.Where(z => tuples.Contains(z.FirstName + "-" + z.Version))
第二个代码示例只是连接两个字段 - 这将对数据库查找产生负面影响(因为它可能需要进行扫描而不是搜索)。如果FirstName
或LastName
包含-
,您可能也会遇到问题。从好的方面来看,它只使用1000个参数而不是2000个。:)
答案 1 :(得分:0)
如果要生成SQL,可以通过显式构建fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:
main.main()
/tmp/sandbox562058728/prog.go:23 +0x14c
子句来避免字符串连接:
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));
是一个用于组合两个表达式的简单实用程序。有关代码,请参见this answer以及对应的Or
。这两种扩展方法在处理表达式时都是无价的。
您现在可以使用此And
表达式来过滤对inTuples
的查询,并且生成的Attributes
子句将匹配所需的形式:
where
您可能需要做些整理才能将结果转换为元组列表:
var filteredQuery = attributesQuery.Where(inTuples).AsEnumerable();
(请注意,为了简化示例,我返回了var resultingTuples = filteredQuery
.Select(a => new {a.Name, a.AttribX})
.AsEnumerable()
.Select(a => (a.FName, a.AttribX))
.ToList();
而不是a.FName
。)