对于以下查询,我得到一个LINQ to SQL异常。
var terms = "bob town".Split(' ');
var q = from m in db.Monument
where terms.All(t => new List<string>() {
m.Name,
m.Street,
m.Owner }.Any(
p => p.Contains(t)))
select m;
例外是:
本地序列不能用于查询的LINQ to SQL实现 除Contains运算符之外的运算符。
如何修改查询以与LINQ to SQL兼容?
目标
查询的目标是这样的。我有一个搜索术语列表和一个包含对象的数据库。如果所有搜索项都是至少一个属性的子字符串,则应返回一个对象。
例如。如果对象o
带有o.name="creek mill"
和o.street="St. Petersroad"
,那么搜索“mill petersroad”应返回此对象,但搜索“mill foobar”不应该。
答案 0 :(得分:1)
因此,实际问题是Linq-To-SQL不知道如何将Linq的Terms
部分转换为有效的SQL语句。因此,您必须重新调整查询以帮助解决问题。
我假设我们希望使用Contains
函数来获取使用SQL IN
运算符的SQL语句。这是我的建议。
var terms = "bob town".Split(' ');
var q = from m in db.Monument
where
terms.Contains(m.Name)
||
terms.Contains(m.Street)
||
terms.Contains(m.Owner)
select m;
我没有对此进行过测试,但它看起来应该可行,应该由Linq-To-SQL转换。
答案 1 :(得分:0)
下面怎么样。我没有试过,但它给你一个关于
的想法var terms = "bob town".Split(' ');
var q = from m in db.Monument
where m.Name.Split(' ').Intersect(terms).Count() > 0 ||
m.Street.Split(' ').Intersect(terms).Count() > 0
select m;
无论如何,我认为对于这种搜索,你应该考虑使用SQL全文搜索,如果你有一个SQL数据库或“.net lucene”,它非常适合你的上下文
答案 2 :(得分:0)
我确信可能有一种方法可以用纯LINQ
做到这一点,但我不确定它是否真的是一个好主意:恕我直言的观点人们有时倾向于过度使用LINQ
除LINQ
之外没有任何特殊原因的查询非常酷,所有这些查询都只是通过查看非常难以理解的查询。
为什么不实施一个带Monument
个实体的扩展方法,并确定某个string[]
符合您的条件?
这样你的LINQ
表达式就不会变得更简单了:
var q = from m in db.Monument
where m.ContainsAllSearchTerms(terms)
select m; //readable and anyone understands right away what is going on here
成为ContainsAllSearchTerms(this Monument m, string[] terms)
相关的扩展方法。