最近一直在研究 EF Core 6,我遇到了一個客戶端評估錯誤,我想知道是否有任何方法可以更有效地重寫它。
我需要Photos根據TagIds. 例如,當通過標簽 [Portugal,Beach] 過濾時,需要獲取包含所有這些標簽的所有照片。因此,包含 [Portugal, Beach, Food] 的照片 X 將被包括在內,但照片 Y [Portugal] 將被排除。
我相信我需要實作這樣的目標,但這會引發客戶端評估例外:
_context.Photo
.Include(i => i.PhotoTags)
.ThenInclude(j => j.Tag)
.Where(i => filter.tagIds.All(j => i.PhotoTags.Exists(k => k.TagId == j)))
有以下課程:
public class Photo
{
public Guid Id { get; set; }
public string Description { get; set; }
public DateTime Date { get; set; }
public bool IsCover { get; set; }
public virtual List<PhotoTag> PhotoTags { get; set; }
}
public class PhotoTag : Base
{
public Guid Id { get; set; }
public Tag Tag { get; set; }
public Guid TagId { get; set; }
public Photo Photo { get; set; }
public Guid PhotoId { get; set; }
}
編輯
這是我得到的錯誤:
System.InvalidOperationException: The LINQ expression 'j => MaterializeCollectionNavigation(
Navigation: Photo.PhotoTags,
subquery: DbSet<PhotoTag>()
.Where(p0 => EF.Property<Guid?>(EntityShaperExpression:
rvc.Models.Photo
ValueBufferExpression:
ProjectionBindingExpression: EmptyProjectionMember
IsNullable: False
, "Id") != null && object.Equals(
objA: (object)EF.Property<Guid?>(EntityShaperExpression:
rvc.Models.Photo
ValueBufferExpression:
ProjectionBindingExpression: EmptyProjectionMember
IsNullable: False
, "Id"),
objB: (object)EF.Property<Guid?>(p0, "PhotoId")))).Exists(k => k.TagId == j)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.VisitLambda[T](Expression`1 lambdaExpression)
at System.Linq.Expressions.Expression`1.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.TranslateInternal(Expression expression)
at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.Translate(Expression expression)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateExpression(Expression expression)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateLambdaExpression(ShapedQueryExpression shapedQueryExpression, LambdaExpression lambdaExpression)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateWhere(ShapedQueryExpression source, LambdaExpression predicate)
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass9_0`1.<Execute>b__0()
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetEnumerator()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at rvc.Services.PhotoService.GetAll(FilterParameters filter) in C:\Users\jjtfs\Work\rvc\server\Services\PhotoService.cs:line 145
uj5u.com熱心網友回復:
這可以通過計算過濾器中的標簽以可翻譯的形式重寫。此計數應等于過濾器中的專案數:
var count = filter.tagIds.Count();
var result = _context.Photo
.Include(p => p.PhotoTags)
.ThenInclude(pt => pt.Tag)
.Where(p => p.PhotoTags.Count(pt => filter.tagIds.Contains(pt.TagId)) == count);
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/462716.html
標籤:C# 林克 实体框架核心 ef-core-6.0
