首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >包含从list到SQL请求的任何字符串的StartsWith和实体框架

包含从list到SQL请求的任何字符串的StartsWith和实体框架
EN

Stack Overflow用户
提问于 2020-12-23 18:12:01
回答 2查看 601关注 0票数 0

我可以通过这样的请求从EF获得对象:

代码语言:javascript
复制
apples = apples.Where(a => a.Sort.Name.StartsWith("Gold"))

但是我想知道是否可以用用户的字符串列表代替一个字符串呢?我已经试过这样做了:

代码语言:javascript
复制
List<string> list = {...}

apples = apples.Where(a => list.Any(x => a.Sort.Name.StartsWith(x)))

但这给了我一个奇怪的错误:

System.ArgumentOutOfRangeException:指定参数超出了有效值的范围。(参数“索引”)在System.Linq.Expressions.InstanceMethodCallExpression1.GetArgument(Int32索引)在Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionVisitors.NpgsqlSqlTranslatingExpressionVisitor.VisitLikeAnyAll(SubQueryExpression表达式)在Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionVisitors.NpgsqlSqlTranslatingExpressionVisitor.VisitSubQuery(SubQueryExpression表达式)在Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.SqlTranslatingExpressionVisitor.Visit(Expression表达式)在Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.SqlTranslatingExpressionVisitor.VisitBinary(BinaryExpression表达式)在Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionVisitors.NpgsqlSqlTranslatingExpressionVisitor.VisitBinary(BinaryExpression表达式)在Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.SqlTranslatingExpressionVisitor.Visit(Expression(在Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.SqlTranslatingExpressionVisitor.VisitBinary(BinaryExpression表达式)在Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionVisitors.NpgsqlSqlTranslatingExpressionVisitor.VisitBinary(BinaryExpression表达式)在Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.SqlTranslatingExpressionVisitor.Visit(Expression表达式)在Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.SqlTranslatingExpressionVisitor.VisitBinary(BinaryExpression表达式)在Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionVisitors.NpgsqlSqlTranslatingExpressionVisitor.VisitBinary(BinaryExpression表达式)在Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.SqlTranslatingExpressionVisitor.Visit(Expression表达式)在Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor.VisitWhereClause(WhereClause whereClause,( Remotion.Linq.QueryModelVisitorBase.VisitBodyClauses(ObservableCollection1 bodyClauses, QueryModel queryModel) at Remotion.Linq.QueryModelVisitorBase.VisitQueryModel(QueryModel queryModel) at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.VisitQueryModel(QueryModel queryModel) at Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor.VisitQueryModel(QueryModel queryModel) at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.CreateAsyncQueryExecutor[TResult](QueryModel queryModel) at Microsoft.EntityFrameworkCore.Storage.Database.CompileAsyncQuery[TResult](QueryModel queryModel) at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileAsyncQueryCore[TResult](Expression query, IQueryModelGenerator queryModelGenerator, IDatabase database) at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass22_01.b__0() at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCoreTFunc at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsyncTResult at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable1.System.Collections.Generic.IAsyncEnumerable.GetEnumerator() at System.Linq.AsyncEnumerable.Aggregate\_[TSource,TAccumulate,TResult](IAsyncEnumerable1 source,TAccumulate seed,Func3 accumulator, Func2 resultSelector,CancellationToken cancellationToken) ( D:\a\1\s\Ix.NET\Source\System.Interactive.Async\Aggregate.cs:line 118 at {my project}

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-12-23 19:10:21

无法获得与您相同的错误(刚刚翻译失败,所以如果您可以添加最小可重现性示例,那就太好了),因为我使用了EF.Functions.ILike (使用最新的npgsql包):

代码语言:javascript
复制
List<string> list = new() {"a%", "b%"};
var result = ctx.Apples
    .Where(c => list.Any(xx => EF.Functions.ILike(c.Sort.Name, xx)))
    .ToList();

据我所见,目前还没有实现对本地集合使用StartsWith的支持(基于这个公关这句话),只有EF.Functions.LikeEF.Functions.ILike

票数 1
EN

Stack Overflow用户

发布于 2020-12-24 01:57:18

如果您愿意使用LINQKit,那么您可以创建扩展方法,从本地集合构建表达式:

代码语言:javascript
复制
// searchTerms - IEnumerable<TSearch> where one must match for a row
// testFne(row,searchTerm) - test one of searchTerms against a row
// r => searchTerms.Any(s => testFne(r,s))
public static Expression<Func<T, bool>> AnyIs<T, TSearch>(this IEnumerable<TSearch> searchTerms, Expression<Func<T, TSearch, bool>> testFne) {
    var pred = PredicateBuilder.New<T>();
    foreach (var s in searchTerms)
        pred = pred.Or(r => testFne.Invoke(r, s));

    return pred;
}

// searchTerms - IEnumerable<TSearch> where one must match for a row
// testFne(row,searchTerm) - test one of searchTerms against a row
// dbq.Where(r => searchTerms.Any(s => testFne(r,s)))
public static IQueryable<T> WhereAny<T,TSearch>(this IQueryable<T> dbq, IEnumerable<TSearch> searchTerms, Expression<Func<T, TSearch, bool>> testFne) =>
    dbq.AsExpandable().Where(searchTerms.AnyIs(testFne));

然后,您可以在查询中使用它们:

代码语言:javascript
复制
List<string> list = {...}

apples = apples.WhereAny(list, (a,s) => a.Sort.Name.StartsWith(s));

当然,您也可以创建自己的mini来完成相同的任务(尽管它并不是很小)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65428974

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档