我有一个标题集合,每个标题都包含一组对象,每个对象都包含一组元数据键值对。例如
> Header
> -> Object
> -> Key value pair
> -> Key value pair
> -> Object
> -> Key value pair
> -> Key value pair
我想使用SQL通配符(使用SqlMethods.Like)返回包含对象的所有标头,其中包含元数据中的某个键值对。
我在下面编写了一个LINQ 2 SQL查询,其中有两个级别的子查询处理方案
string filePath = "ab%cd";
var dbHeaders = from h in _repository.GetHeaders()
where
(from o in h.Objects
where
(from mdp in o.MetaDataPairs
where mdp.Key == Constants.FilePath && SqlMethods.Like(mdp.Value.ToLower(), filePath))
select mdp
).Any()
select o).Any()
select h;
这很好用。
当我有一个可供搜索的搜索值列表时,会出现问题。即我想从可能的匹配列表中找到包含元数据值的对象,而不仅仅是单个匹配。我尝试了下面的内容。
var filePaths = new List<string> { "ab%cd", "ef%gh" };
var dbHeaders = from h in _repository.GetHeaders()
where
(from o in h.Objects
where
(from mdp in o.MetaDataPairs
where mdp.Key == Constants.FilePath && filePaths.Any(fp => SqlMethods.Like(mdp.Value.ToLower(), fp))
select mdp
).Any()
select o).Any()
select h;
但是因为SQLMethods.Like包含在Filepaths.Any()中,所以它不起作用。因为它必须在LINQ 2 SQL查询中本地发生。
如何使用SQL Like运算符修改要匹配的顶级查询,以便检查字符串搜索令牌列表,而不是单个?
更新:错误消息
Assert.IsFalse失败。发生意外错误:LINQ to Entities 无法识别方法&#39;布尔类似(System.String, System.String)&#39;方法,这个方法无法翻译成一个 商店表达。
答案 0 :(得分:0)
正如您所提到的,问题是,一旦您将SqlMethods.Like
放入filePaths.Any
,它就会引发异常。
这是因为linq-to-entity不支持SqlMethods.Like
,filePath
是实体。
您需要以某种方式使用OR
动态创建多个SqlMethods.Like
语句。
我发现了一个非常相似的问题和一个应该有用的有趣答案: How can I add variable count of SqlMethods.Like() in one query?
该解决方案利用了来自 C#6.0 in Nutshell 的PredicateBuilder。
我相信您可以将您的代码调整为以下内容:
我没有测试代码,当然。
var filePaths = new List<string> { "ab%cd", "ef%gh" };
var likeExpression = PredicateBuilder.False<MetaDataPairClassName>();
foreach (string filePath in filePaths)
{
likeExpression = likeExpression.Or(mdp =>
SqlMethods.Like(mdp.Value.ToLower(), filePath));
}
var dbHeaders = from h in _repository.GetHeaders()
where
(from o in h.Objects
where
(from mdp in o.MetaDataPairs
.Where(mdp.Key == Constants.FilePath)
.Where(likeExpression))
select mdp
).Any()
select o).Any()
select h;