如果您try 查找包含查询中的流派的实体(它们也可能包含查询中不包含的其他流派),则会出现错误.我try 了许多 Select ,但最终收到了3个请求.

Genres是一个列表字符串.

query = query.Where(g => request.genres.All(r => g.Genres.Any(gameGenre => gameGenre.Equals(new StringForGame(r)))));

System.InvalidOperationException:LINQ表达式‘r=>ShaedQueryExpression: 查询表达式: 投影贴图: EmptyProjectionMember->EntiyProjectionExpression:StringForGame Select 1 从游戏流派到g ShaperExpression:EntiyShaperExpression: GameProfile.Domain.Entities.GameEntites.Game.Genres#StringForGame ValueBufferExpression: 项目绑定表达式:EmptyProjectionMember IsNullable:False

.Where(名称参数{0}=>对象.等于( ObjA:(Object)EF.Property(EntityShaperExpression: GameProfile.Domain.Entities.GameEntites.Game ValueBufferExpression: 项目绑定表达式:EmptyProjectionMember IsNullable:False ,"ID"), ObjB:(Object)EF.Property(nameless参数{0},"GameID")) .AsQueryable() .无法翻译Any(o=>o.GameString.Equals(new StringForGame(R)‘.

query = query.Where(g => g.Genres.Any(gg => request.genres.All(r=> gg.GameString == r)));

System.InvalidOperationException:LINQ表达式‘r=>EntityShaperExpression: GameProfile.Domain.Entities.GameEntites.Game.Genres#StringForGame ValueBufferExpression: 项目绑定表达式:EmptyProjectionMember IsNullable:False 无法转换.GameString==r‘.

这个查询可以工作,但没有给出我需要的结果.

query = query.Where(g => g.Genres.Any(gg => request.genres.Contains(gg.GameString)));
// and this too
query = query.Where(g => g.Genres.All(gg => request.genres.Contains(gg.GameString)));

对于上下文

public async Task<List<Game>> Handle(GetGamesQuery request, CancellationToken cancellationToken)
{
        var query = _context.Games.AsQueryable();

        if (request.sort == "titleAtoZ")
        {
            query = query.OrderBy(x => x.Title);
        }
        else if (request.sort == "titleZtoA")
        {
            query = query.OrderByDescending(x => x.Title);
        }
        else if (request.sort == "dateAscending")
        {
            query = query.OrderBy(x => x.ReleaseDate);
        }
        else if (request.sort == "dateDescending")
        {
            query = query.OrderByDescending(x => x.ReleaseDate);
        }

        if (request.releaseDateOf != DateTime.MinValue && request.releaseDateTo != DateTime.MinValue)
        {
            query = query.Where(x => x.ReleaseDate >= request.releaseDateOf && x.ReleaseDate <= request.releaseDateTo);
        }
        else if (request.releaseDateOf == DateTime.MinValue && request.releaseDateTo != DateTime.MinValue)
        {
            query = query.Where(x => x.ReleaseDate <= request.releaseDateTo);
        }
        else if (request.releaseDateOf != DateTime.MinValue && request.releaseDateTo == DateTime.MinValue)
        {
            query = query.Where(x => x.ReleaseDate >= request.releaseDateOf);
        }

        if (request.nsfw == "yes")
        {
            query = query.Where(x => x.Nsfw == true);
        }
        else if (request.nsfw == "no")
        {
            query = query.Where(x => x.Nsfw == false);
        }

        if (request.genres is not null && request.genres.Count > 0)
        {
            query = query.Where(g => g.Genres.Any(gg => request.genres.Contains(gg.GameString)));
            //query = query.Where(g => g.Genres.Any(gg => request.genres.All(r=> gg.GameString == r)));
            //query = query.Where(g => request.genres.All(r => g.Genres.Any(gameGenre => gameGenre.Equals(new StringForGame(r)))));
        }

        int skipGame = request.page * 50;
        query = query.Skip(skipGame).Take(50);
        var games = await query.ToListAsync(cancellationToken);

        return games;
}

public sealed class Game : Entity
{
    public Game(Guid id,
                string title,
                DateTime releaseDate,
                Uri headerImage,
                bool nsfw,
                string description,
                ICollection<StringForGame> developers,
                ICollection<StringForGame> publishers,
                ICollection<StringForGame> genres,
                ICollection<UriForGame> screenshots,
                ICollection<UriForGame> shopsLinkBuyGame,
                int achievementsCount) : this(id,title,releaseDate,headerImage,nsfw,description,achievementsCount)
    {
        Developers = developers;
        Publishers = publishers;
        Genres = genres;
        Screenshots = screenshots;
        ShopsLinkBuyGame = shopsLinkBuyGame;
    }

    /// <summary>
    /// EF constructor
    /// </summary>
    private Game(Guid id,
                string title,
                DateTime releaseDate,
                Uri headerImage,
                bool nsfw,
                string description,
                int achievementsCount) : base(id)
    {
        Title = title;
        ReleaseDate = releaseDate;
        HeaderImage = headerImage;
        Nsfw = nsfw;
        Description = description;
        AchievementsCount = achievementsCount;
    }

    public string Title { get; private set; }
    public DateTime ReleaseDate { get; private set; }
    public Uri HeaderImage { get; private set; }
    public bool Nsfw { get; private set; }
    public string Description { get; private set; }

    public ICollection<UriForGame> Screenshots { get; private set; }
    public ICollection<StringForGame> Genres { get; private set; }
}

public sealed class StringForGame : ValueObject
{
    public StringForGame(string gameString)
    {
        GameString = gameString;
    }

    public string GameString { get; private init; }
    
    public override IEnumerable<object> GetAtomicValues()
    {
        yield return GameString;
    }
}

public abstract class ValueObject : IEquatable<ValueObject>
{
    public abstract IEnumerable<object> GetAtomicValues();

    public bool Equals(ValueObject? other)
    {
        return other is not null && ValuesAreEqual(other);
    }

    public override bool Equals(object? obj)
    {
        return obj is ValueObject valueObject && ValuesAreEqual(valueObject);
    }

    public override int GetHashCode()
    {
        return GetAtomicValues().Aggregate(default(int), HashCode.Combine);
    }

    private bool ValuesAreEqual(ValueObject other)
    {
        return GetAtomicValues().SequenceEqual(other.GetAtomicValues());
    }
}

我真的不知道问题出在哪里,如果有任何帮助,我将不胜感激.

使用的版本:EF Core 7.0.8

推荐答案

相对众所周知的是,在所有EF("classic "和核心)版本中,LINQ to Entities查询内的in memory个集合上唯一受支持的方法是Contains.

它适用于Any个类型标准,如

query.Any(x => collection.Contains(Field(x)))

但不适用于像这样的All种类型标准

query.All(x => collection.Contains(Field(x)))

这很可能是因为缺少相应的SQL构造(即使他们对其他一些LINQ表达式也是这样做的).

通常(也是唯一已知的)解决方法是使用LINQ All的类似功能"计算匹配项"

query.Count(x => collection.Contains(Field(x))) == collection.Count()

(在某些版本中,您可能需要将collection.Count()存储在查询外部的变量中,并在内部使用该变量).

话虽如此,在您的 case 中,解决方案类似于

query = query.Where(g => 
    g.Genres.Count(gg => request.genres.Contains(gg.GameString)) == request.Genres.Count()
);

Csharp相关问答推荐

如果第一个匹配项为空,则规则运算不会拆分C#中分离字符串上的子菜单

循环访问Android视图中动态创建的子视图

无法使用并行库并行化我的代码

Dapper是否可以自动扩展类成员

当打印一行x个项目时,如何打印最后一行项目?

System.Text.Json数据化的C#类映射

. NET 8控制台应用程序DI错误无法解析Microsoft. Extension. Logging. ILoggerFactory类型的服务'''

如何定义EFCore中的多个穿透

从c#列表中删除额外的对象&对象&>从ASP.NET WebForm返回json响应

如何将不同类型的扩展参数的javascript函数转换成C#风格?

.NET SDK包中的官方C#编译器在哪里?

try 在.Net核心身份注册页面中使用AJAX,但没有成功..NET Core 5.0 Razor页面应用程序

如何在VS代码中为C#DotNet配置.json选项以调试内部终端的控制台应用程序

VS 2022 for ASP.NET Core中缺少自定义项模板

EF核心区分大小写的主键

委托RequestDelegate不带2个参数-ASP.NET Core 8最小API

如何从非异步任务中正确返回TypeResult

如何从Azure函数使用Graph API(SDK 5.35)中的[FindMeetingTimes]

Xamarin.Forms中具有类似AspectFill的图像zoom 的水平滚动视图

Xamarin Forms应用程序中登录页面的用户名和密码编辑文本之间不需要的空格