使用带有 NHibernate 的网络 api 通过 JSON 插入嵌套的 object

Insert nested object via JSON using web api with NHibernate

我正在编写一个包含读取API 和写入API 的应用程序。读取 API 包含域 classes,并首先使用 EF CORE 代码生成 SQL 数据库,并从中读取。

write API 使用 NHibernate 写入由 EF Core 生成的数据库。到目前为止,我已经通过写入 API 插入了 'simple' object,效果很好。

我现在遇到了一个问题。我有一个域 class,Driver,里面有一个嵌套的 object,地址。在数据库级别,一个 driver 可以有一个地址,一个地址可以属于多个 driver。我正在尝试 POST a JSON object,a driver object,通过写入 API。至于现在,我已经通过预先在DB中创建地址记录并在JSON中给出地址ID来解决插入地址。

我现在要做的是提供完整的嵌套 JSON object 并让 NHibernate 为我生成插入内容。我已经尝试了很多东西,但我觉得我无处可去。任何建议将不胜感激。

我将 .Net Core 与 NHiberate 5.3.5 一起使用,它已经具有代码映射功能。如果有人可以使用 Fluent NH 解决它,那也很好,因为我会自己将其转换为 NH 5.3.5 表示法。

我的代码:

域 classes:

Driver:

namespace Models
{
    public class Chauffeur : IIdentifiable
    {
        public virtual long Id { get; set; }
        public virtual string Naam { get; set; }
        public virtual string Voornaam { get; set; }
        public virtual DateTime GeboorteDatum { get; set; }
        //todo validatie
        public virtual string RijksRegisterNummer { get; set; }
        public virtual RijbewijsTypes TypeRijbewijs { get; set; }
        public virtual bool Actief { get; set; }

        //rel adres
        public virtual long AdresId { get; set; }
        public virtual Adres Adres { get; set; }

        //rel tankkaart
        public virtual long TankkaartId { get; set; }
        public virtual Tankkaart Tankkaart { get; set; }

    }
}

地址:

namespace Models
{
    public class Adres : IIdentifiable
    {
        public virtual long Id { get; set; }
        public virtual string Straat { get; set; }
        public virtual int Nummer { get; set; }
        public virtual string Stad { get; set; }
        public virtual int Postcode { get; set; }
        public virtual ICollection<Chauffeur> Chauffeurs { get; set; }
    }
}

我的Driver到目前为止的地图:

namespace WriteAPI
{
    public class ChauffeurMap : ClassMapping<Chauffeur>
    {
        public ChauffeurMap()
        {
            this.Table("Chauffeurs");

            this.Id(c => c.Id, c =>
            {
                c.Generator(Generators.Native);
                c.Type(NHibernateUtil.Int64);
                c.Column("Id");
                c.UnsavedValue(0);
            });
            
            this.Property(c => c.Naam);
            this.Property(c => c.Voornaam);
            this.Property(c => c.GeboorteDatum);
            this.Property(c => c.RijksRegisterNummer);
            this.Property(c => c.TypeRijbewijs);
            this.Property(c => c.Actief);

            this.Property(c => c.AdresId);

            this.Property(c => c.TankkaartId);
        }
    }
}

使用此映射,我可以使用现有的 child 地址 ID 插入嵌套的 object。

我是如何通过 post 插入这个的:

{
                "Naam" : "Bart",
                "Voornaam" : "Jannsses",
                "AdresId" : 4,
                "GeboorteDatum" : "1979-04-25",
                "RijksRegisterNummer" : "999-888-7777",
                "TypeRijbewijs" : 1,
                "Actief" : true
}

以后想怎么插入:

{
                "Naam" : "Bart",
                "Voornaam" : "Jannsses",
                "Adres" : {
                    "Straat": "Boomstraat", 
                    "Nummer": 1, 
                    "Stad": "Gent", 
                    "Postcode": 9000
                          },
                "GeboorteDatum" : "1979-04-25",
                "RijksRegisterNummer" : "999-888-7777",
                "TypeRijbewijs" : 1,
                "Actief" : true
}

请注意,地址 ID 是在数据库级别自动生成的。

如有任何帮助,我们将不胜感激。

亲切的问候

您需要在 ChauffeurMap class

中添加 ManyToOne 映射
 this.ManyToOne(x => x.Adres , m =>
        {
            m.Column("AdresId");
            // AdresId can be insert and update
            m.Update(true);
            m.Insert(true);
            m.Cascade(Cascade.None);
            m.Fetch(FetchKind.Join);
            m.NotFound(NotFoundMode.Exception);
            m.Lazy(LazyRelation.Proxy);
            m.ForeignKey("AdresId");
        });

您还需要将 Adres 的 class 映射为 AdresMap。我希望你已经拥有它。如果没有,请添加如下 -

public class AdresMap : ClassMapping<Adres> 
{
    public AdresMap()
    {
    this.Table("Adres"); //Your table name
    this.Id(c => c.Id, c =>
        {
            c.Generator(Generators.Native);
            c.Type(NHibernateUtil.Int64);
            c.Column("Id");
            c.UnsavedValue(0);
        });

    Set(x => x.Chauffeurs, c =>
        {
            c.Key(k =>
                {
                    k.Column("Id");
                    k.ForeignKey("AdresId");
                });
            c.Inverse(true);
            c.Cascade(Cascade.None);
        },
        r => r.OneToMany(o => { }));

    this.Property(x => x.Straat );
    // ... other properties
   }
}