EFCORE8 Postgresql 在 LINQ 中使用 all 和 contains 时无法翻译

问题描述 投票:0回答:1

我有一个名为 MapInfo 的模型,其中包含 MapTags 字段。

我想带入一个List来查找数据库中是否有匹配的项,就像下面的SQL语法。

select * from "MapInfo"
where "MapInfo"."MapTags" @> ARRAY[0,1000];

我也想使用 LINQ 做同样的事情。

但是当我使用 LINQ 搜索数据时,我收到一条错误消息。

查询码

IQueryable<MapInfo> query = dbContext.MapInfo.AsNoTracking();

// Method 1
query = query.Where(map => map.MapTags != null && param.MapTags.All(tag => map.MapTags.Contains(tag)));
// Method 2
query = query.Where(map => param.MapTags.All(tag => map.MapTags.Any(t => t == tag)));
// Method 3
query = query.Where(map => map.MapTags != null);
foreach (var tag in param.MapTags)
{
    query = query.Where(map => map.MapTags.Any(v => v == tag));
}
// Method 4
query = query.Where(map => map.MapTags != null);
foreach (var tag in param.MapTags)
{
    query = query.Where(map => map.MapTags.Contains(tag));
}

错误信息

 System.InvalidOperationException : The LINQ expression '__param_MapTags_0
    .All(e => StructuralTypeShaperExpression: 
        MapInfo
        ValueBufferExpression: 
            ProjectionBindingExpression: EmptyProjectionMember
        IsNullable: False
    .MapTags
        .Contains(e))' could not be translated. Additional information: Translation of method 'System.Linq.Enumerable.Contains' failed.

数据模型

// setting in DbContext
modelBuilder.Entity<MapInfo>().Property(e => e.MapTags).HasConversion<List<int>>();

[Serializable]
public class MapInfo
{
    [Key]
    public Guid Guid { get; set; }
    [Required]
    public string UserId { get; set; } = null!;
    public string Title { get; set; } = null!;
    public List<MapTag> MapTags { get; set; }
    public DateTime CreatedAt { get; set; }
}

public enum MapTag
{
    Group1 = 1000,
    Group2 = 1001,
    Group3 = 1002,
}

尝试了很多方法查询还是失败。

我还阅读了https://www.npgsql.org/efcore/mapping/array.html并且

array1.All(i => array2.Contains(i))
应该可以工作。

我的代码或设置有什么问题吗?

c# linq ef-core-8.0
1个回答
0
投票

更新

我发现模型设置错误。 正确的设置List方式是

modelBuilder.Entity<MapInfo>(info =>
{
    info.PrimitiveCollection(c => c.MapTags).ElementType(e => e.HasConversion(typeof(EnumToNumberConverter<MapTag, int>)));
});

最后是框架版本问题导致的。

当我使用 EF CORE 8.0.1时它可以工作。

但升级到8.0.4后就不能再使用了。

我不确定这是 EFCORE 问题还是 Npgsql 问题。

我会向他们提出问题。

© www.soinside.com 2019 - 2024. All rights reserved.