gpt4 book ai didi

c# - LINQ 到实体 : Orderby statement involving extension method

转载 作者:太空宇宙 更新时间:2023-11-03 19:16:33 25 4
gpt4 key购买 nike

我正在为网站构建一个简单的搜索功能。目的是让用户能够找到“游泳者”,并通过搜索框将他们添加到列表中,使用诸如“bob staff”之类的查询。

我决定解决的第一部分是允许用户通过组名进行搜索(在数据库中,所有游泳者都是组的一部分)。以下是我目前的代码。

[HttpGet]
public JsonResult searchForSwimmers(string q)
{
//designed to return [{name='foo',id='bar'}]

String[] QueryTerms = q.Split(' '); //all the search terms are sep. by " "
var groupResults = _db.SwimGroups.Where(g => g.Name.ContainsAny(QueryTerms))
.OrderByDescending(g => g.Name.StartsWithAny(QueryTerms) ? 1 : 0)
.ThenBy( g => g)
.Select(g => new { name = g.Name, id = g.ID });


return Json(groupResults,JsonRequestBehavior.AllowGet);
}

在第 8 行,调用了一个名为 StartsWithAny 的方法。这是我在以下文件中定义的扩展方法:

public static class StringUtils
{
public static Boolean StartsWithAny(this String str, params String[] Fragments)
{
foreach (String fragment in Fragments)
{
if (str.StartsWith(fragment))
{
return true;
}
}
return false;
}
}

想法是,如果一个名称以其中一个术语开头,那么它的相关性应该排名更高。我认识到这种逻辑是幼稚的并且有缺陷,但我认为这将是一个很好的例子来说明我遇到的问题。但是,当在我的 cshtml 页面中使用以下内容调用 searchForSimmers 时,代码会编译:(使用 tokenInput 库)

<script type="text/javascript">
$(document).ready(function () {
$("#demo-input-local").tokenInput("/Admin/searchForSwimmers");
});
</script>

我收到 500 内部服务器错误。错误信息如下:

LINQ to Entities does not recognize the method 'Boolean ContainsAny(System.String, System.String[])' method, and this method cannot be translated into a store expression.

ContainsAny 方法

public static Boolean ContainsAny(this String str, List<String> Fragments)
{
foreach (String fragment in Fragments)
{
if(str.Contains(fragment))
{
return true;
}
}
return false;
}

我环顾四周,但找不到问题的解决方案。任何帮助将不胜感激,干杯。

最佳答案

查看我的博客,我在其中为 IQueryable 创建了一个搜索扩展方法。

更新:我创建了一篇新博文,展示了实现您的目标所需的扩展方法

http://www.ninjanye.co.uk/2013/04/generic-iqueryable-or-search-for.html

http://jnye.co/Posts/8/generic-iqueryable-or-search-for-multiple-search-terms-using-expression-trees

问题是 linq 不知道如何将您的代码翻译成 SQL。

通过添加以下扩展方法:

public static class QueryableExtensions
{
public static IQueryable<T> Search<T>(this IQueryable<T> source, Expression<Func<T, string>> stringProperty, params string[] searchTerms)
{
if (!searchTerms.Any())
{
return source;
}

Expression orExpression = null;
foreach (var searchTerm in searchTerms)
{
//Create expression to represent x.[property].Contains(searchTerm)
var searchTermExpression = Expression.Constant(searchTerm);
var containsExpression = BuildContainsExpression(stringProperty, searchTermExpression);

orExpression = BuildOrExpression(orExpression, containsExpression);
}

var completeExpression = Expression.Lambda<Func<T, bool>>(orExpression, stringProperty.Parameters);
return source.Where(completeExpression);
}

private static Expression BuildOrExpression(Expression existingExpression, Expression expressionToAdd)
{
if (existingExpression == null)
{
return expressionToAdd;
}

//Build 'OR' expression for each property
return Expression.OrElse(existingExpression, expressionToAdd);
}

private static MethodCallExpression BuildContainsExpression<T>(Expression<Func<T, string>> stringProperty, ConstantExpression searchTermExpression)
{
return Expression.Call(stringProperty.Body, typeof(string).GetMethod("Contains"), searchTermExpression);
}

}

这将允许您编写以下 lambda:

[HttpGet]
public JsonResult searchForSwimmers(string q)
{
//designed to return [{name='foo',id='bar'}]

String[] QueryTerms = q.Split(' '); //all the search terms are sep. by " "
var groupResults = _db.SwimGroups.Search(g => g.Name, queryTerms)
.OrderByDescending(g => g.Name.StartsWithAny(QueryTerms) ? 1 : 0)
.ThenBy( g => g)
.Select(g => new { name = g.Name, id = g.ID });

return Json(groupResults,JsonRequestBehavior.AllowGet);
}

关于c# - LINQ 到实体 : Orderby statement involving extension method,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16215100/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com