#.net-core #nhibernate #asp.net-core-webapi #fluent-nhibernate-mapping
#.net-ядро #nhibernate #asp.net-ядро-webapi #fluent-nhibernate-отображение
Вопрос:
Я пишу приложение, состоящее из ReadAPI и WriteAPI. API чтения содержит классы домена и использует код ядра EF сначала для генерации базы данных SQL и для чтения из нее.
API записи использует NHibernate для записи в базу данных, которая генерируется EF Core. До сих пор я вставлял «простой» объект через write API, который работал нормально.
Сейчас я столкнулся с проблемой. У меня есть доменный класс Driver, внутри которого есть вложенный объект Address. На уровне базы данных драйвер может иметь один адрес, а адрес может принадлежать нескольким драйверам. Я пытаюсь ОПУБЛИКОВАТЬ объект JSON, объект драйвера, через write API. На данный момент я решил вставить адрес, заранее создав запись адреса в базе данных и указав идентификатор адреса в JSON.
Что я хочу сделать сейчас, так это предоставить полный вложенный объект JSON и попросить NHibernate сгенерировать вставки для меня. Я перепробовал так много вещей, но чувствую, что у меня ничего не получается. Любой совет был бы очень признателен.
Я использую .Net Core с NHiberate 5.3.5, в котором уже есть функциональность отображения по коду. Если кто-то может решить эту проблему, используя вместо этого Fluent NH, это тоже хорошо, так как тогда я сам преобразовал его в нотацию NH 5.3.5.
Мой код:
Классы домена:
Драйвер:
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; }
}
}
Моя карта драйверов до сих пор:
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);
}
}
}
Используя это сопоставление, я мог бы вставить вложенный объект, используя существующий идентификатор дочернего адреса.
Как я вставил это через сообщение:
{
"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
}
Обратите внимание, что идентификатор адреса автоматически генерируется на уровне базы данных.
Любая помощь была бы очень признательна.
С наилучшими пожеланиями
Комментарии:
1. Не могли бы вы поделиться кодом, в котором фактически происходит вставка базы данных? Это может помочь дать некоторый дополнительный контекст.
Ответ №1:
Вам нужно будет добавить ManyToOne
сопоставление в свой ChauffeurMap
класс
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
as 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
}
}