簡體   English   中英

StartsWith 與列表中的任何字符串到 SQL 請求與 LINQ 和實體框架

[英]StartsWith with any string from list to SQL request with LINQ and Entity Framework

我可以通過這樣的請求從 EF 獲取對象:

apples = apples.Where(a => a.Sort.Name.StartsWith("Gold"))

但我想知道是否可以使用字符串列表而不是一個字符串? 我已經嘗試過這樣做:

List<string> list = {...}

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

但它給了我奇怪的錯誤:

System.ArgumentOutOfRangeException:指定的參數超出了有效值的范圍。 (Parameter 'index') at System.Linq.Expressions.InstanceMethodCallExpression1.GetArgument(Int32 index) at Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionVisitors.NpgsqlSqlTranslatingExpressionVisitor.VisitLikeAnyAll(SubQueryExpression expression) at Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionVisitors.NpgsqlSqlTranslatingExpressionVisitor .VisitSubQuery(SubQueryExpression expression) at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.SqlTranslatingExpressionVisitor.Visit(Expression expression) at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.SqlTranslatingExpressionVisitor.VisitBinary(BinaryExpression expression) at Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionVisitors.NpgsqlSqlTranslatingExpressionVisitor .VisitBinary(BinaryExpression 表達式)在 Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.SqlTranslatingExpressionVisitor.Visit(表達式)在 Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.SqlT ranslatingExpressionVisitor.VisitBinary(BinaryExpression expression) at Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionVisitors.NpgsqlSqlTranslatingExpressionVisitor.VisitBinary(BinaryExpression expression) at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.SqlTranslatingExpressionVisitor.Visit(Expression expression) at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors. SqlTranslatingExpressionVisitor.VisitBinary(BinaryExpression expression) at Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionVisitors.NpgsqlSqlTranslatingExpressionVisitor.VisitBinary(BinaryExpression expression) at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.SqlTranslatingExpressionVisitor.Visit(Expression expression) at Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor.在 Remotion.Linq.QueryModelVisitorBase.VisitBodyClauses(ObservableCollection 1 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_0 1 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_0 1.b__0() 在 Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](對象 cacheKey,Func 1 compiler) at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query) at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable 壓力1 compiler) at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query) at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable 1.System.Collections.Generic.IAsyncEnumerable.GetEnumerator() 在 System.Linq.AsyncEnumerable.Aggregate_[TSource,TAccumulate,TResult](IAsyncEnumerable 1 source, TAccumulate seed, Func 3 累加器,Func`2 resultSelector,CancellationToken cancellationToken) 在 D:\a\1\s\Ix.NET\Source\System.Interactive.Async\Aggregate.cs:line 118 at {my project}

無法得到與您相同的錯誤(只是翻譯失敗,所以如果您可以添加最小的可重現示例會很棒),因為我使用EF.Functions.ILike (帶有最新的 npgsql 包):

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

據我所知,目前還沒有實現對本地集合使用StartsWith的支持(基於這個 PR這個評論),只有EF.Functions.LikeEF.Functions.ILike

如果您願意使用LINQKit ,那么您可以創建擴展方法來從本地 collections 構建表達式:

// 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));

然后您可以將它們用於您的查詢:

List<string> list = {...}

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

當然,您也可以創建自己的迷你 LINQKit 來完成相同的任務(盡管它不是那么迷你)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM