将JSON数组对象字段中的数据与另一个表连接

问题描述

可以说,我在Postgre数据库上有两个表,如下所示:

CREATE TABLE "MST"."Users" (
  "Id" uuid NOT NULL DEFAULT uuid_generate_v4(),"Uid" varchar(32) COLLATE "pg_catalog"."default" NOT NULL,"Pid" varchar(100) COLLATE "pg_catalog"."default" NOT NULL,"Details" jsonb,"Contacts" jsonb,"Trackers" jsonb NOT NULL,"Configurations" jsonb,PRIMARY KEY ("Id"),UNIQUE ("Uid")
);

CREATE TABLE "MST"."Teams" (
  "Id" uuid NOT NULL DEFAULT uuid_generate_v4(),"Details" jsonb NOT NULL,"Members" jsonb,PRIMARY KEY ("Id")
);

这两个表都映射了以下模型:

    [Table("Users",Schema = "MST")]
    public partial class Users
    {
        [Key]
        public Guid Id { get; set; }
        
        [Required]
        [StringLength(32)]
        public string Uid { get; set; }
        
        [Required]
        [StringLength(100)]
        public string Pid { get; set; }

        [Column(TypeName = "jsonb")]
        public UserDetailsModel Details { get; set; }

        [Column(TypeName = "jsonb")]
        public UserContactsModel Contacts { get; set; }

        [Required]
        [Column(TypeName = "jsonb")]
        public TrackersModel Trackers { get; set; }

        [Column(TypeName = "jsonb")]
        public UserConfigurationsModel Configurations { get; set; }
    }

    [Table("Teams",Schema = "MST")]
    public partial class Teams
    {
        [Key]
        public Guid Id { get; set; }

        [Required]
        [Column(TypeName = "jsonb")]
        public TeamDetailsModel Details { get; set; }
        
        [Column(TypeName = "jsonb")]
        public List<TeamMembersModel> Members { get; set; }

        [Required]
        [Column(TypeName = "jsonb")]
        public TrackersModel Trackers { get; set; }
    }

    // Childs classes
    public class TeamMembersModel
    {
        [Required(ErrorMessage = @"Member ""User ID"" is required and can not be empty.")]
        [StringLength(maximumLength: 32,MinimumLength = 3,ErrorMessage = @"Member ""User ID"" length must be between 3 and 32 chars.")]
        public string Uid { get; set; }

        public bool IsLead { get; set; } = false;

        public UserDetailsModel Details { get; set; }
    }

    public UserContactModel { 
        ...some properties...
    }

    public TrackersModel { 
        ...some properties...
    }

    public UserDetailsModel { 
        ...some properties...
    }

以下是团队表中的数据样本:

INSERT INTO "MST"."Teams"("Id","Details","Members","Trackers") VALUES ('daf0e3d3-78bf-443b-8b0b-6f74d2eabd7f','{"Name": "My First Team","Files": [],"Notes": null,"Photo": null}','[{"Uid": "fadhly.permata","IsLead": true},{"Uid": "humaira.permata","IsLead": false}]','{"Status": "RG","Created": {"At": "2020-08-14T12:15:59.4175028+00:00","By": "SYSTEM"},"Updated": null}');

INSERT INTO "MST"."Teams"("Id","Trackers") VALUES ('538f1d58-01cb-4120-b89a-ea25bfacaa25','{"Name": "My Second Team","IsLead": true,"Details": null}]',"Created": {"At": "2020-08-19T10:51:44.5128139+00:00","By": "fadhly.permata"},"Updated": null}');

您可以在我的数据库数据中看到,成员字段存储有JSON数组。我对如何将Teams-> Members-> Details与Users表中的详细信息结合在一起感到困惑。

这是我的查询:

from
    team in _manager.DbContext.Teams

where
    team.Trackers.Status != "DE"

orderby
    team.Details.Name

select
    new Models.Teams
    {
        Id = team.Id,Details = team.Details,Trackers = team.Trackers,Members = team.Members.Select(
            x => new TeamMembersModel { 
                Uid = x.Uid,IsLead = x.IsLead,Details = _manager.DbContext.Users.First(y => y.Uid == x.Uid).Details 
            }
        )
            .ToList()
    };

但是我对上面的查询不走运,并收到以下错误消息: "Object reference not set to an instance of an object."

也许我错过了一些东西,但是不确定它在哪里。


注意: 我也使用NPGSQL作为EF引擎的附加功能/扩展功能,正如我也在此问题标签上添加的一样。

解决方法

问题出在team.Members的投影上,它是一个JSON属性而不是EF导航-无法将其转换为SQL以便在PostgreSQL中进行处理。由于这是最终的预测,因此应该对客户进行评估,但是EF似乎对此有一个错误(已打开https://github.com/dotnet/efcore/issues/22161进行跟踪)。

如果打算让它进行客户评估,只需在投影之前放置一个AsEnumerable-这样就可以消除错误。否则,

从理论上讲,这可以通过将JSON数组投影转换为json_array_elementssee PG docs)来完成,但是提供者极不可能很快就能做到这一点。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...