8

次の2つのクラスがあります。

広告

public virtual int Id { get; set;
public virtual IList<AdvertImage> AdvertImages { get; set; }

AdvertImage

public virtual int Id { get; set; }
public virtual string Filename { get; set;
public virtual Advert Advert { get; set; }

DBでは、AdvertImagesテーブルにFK'AdvertId'があり、これはPKが'Id'であるAdvertsテーブルに関連しています。

これは1対多のマッピングであり、1つの広告に多くの画像を含めることができます。

私のFluentNHibernateマッピング(簡潔にするために編集)は次のとおりです。

AdvertMap

Id(x => x.Id)
  .GeneratedBy.Identity();
...
HasMany(x => x.AdvertImages)
  .KeyColumn("AdvertId")
  .Inverse();
...
Table("Adverts");

AdvertImageMap

Id(x => x.Id)
  .GeneratedBy.Identity();
...
References(x => x.Advert)
  .Column("AdvertId");
...
Table("AdvertImages");

Advertコード内の新しいインスタンスを作成してから、AdvertImages(Advertの)プロパティに。を入力していList<AdvertImage>ます。

オブジェクトをDBに永続化するときにAdvert、AdvertImagesをAdvertImagesテーブルに挿入したいのですが、2つのテーブル間の関係により、PK Idが生成されるように、最初にAdvert挿入を行う必要があります。 、AdvertImagesテーブルに挿入できます。(AdvertImageのリストを作成するとき、Filenameプロパティにデータを入力していますが、その段階では明らかに新しいAdvertIdがないため、広告がDBに永続化されるときにデータを入力する必要があります)。

さまざまなInverse()とCascadeの設定を試してみましたが、まだ成功していません。誰か助けてもらえますか?

4

3 に答える 3

10

Advertマッピングをカスケードに変更する必要があります。

Id(x => x.Id)
  .GeneratedBy.Identity();

HasMany(x => x.AdvertImages)
  .KeyColumn("AdvertId")
  .Inverse()
  .Cascade.AllDeleteOrphan();

Table("Adverts");

そうすれば、このようなことを実行して、Advertオブジェクトとその子を永続化できるはずAdvertImageです。

Advert newAdvert = new Advert();
AdvertImage newImage = new AdvertImage();
newImage.Advert = newAdvert;
newAdvert.AdvertImages.Add(newImage);

using(NHibernate.ISession session = SessionFactory.GetCurrentSession())
{
    using (NHibernate.ITransaction tran = session.BeginTransaction())
    {
        session.Save(newAdvert);
        tran.Commit();
    }
}

私のエンティティには通常、次のような双方向の1対多の関係のためのAddメソッドとRemoveメソッドが含まれています。

public class Advert
{
    public virtual IList<AdvertImage> AdvertImages { get; set; }

    public virtual void AddImage(AdvertImage newImage)
    {
        newImage.Advert = this;
        AdvertImages.Add(newImage);
    }
}
于 2012-06-01T18:19:38.520 に答える
2

私も同じ問題を抱えていました。さまざまな種類のマッピングをすべて試してみました。次に、マッピングに問題がないことを発見しました。実際には、セッションをトランザクションでラップし、session.SaveOrUpdate()メソッドの後にCommit()メソッドを使用する必要がありました。

using(var session = sessionFactory.OpenSession()) 
using(var tx = session.BeginTransaction()) 
{ 
// execute code that uses the session 
tx.Commit(); 
}
于 2014-01-21T14:36:21.477 に答える
1

私にとって通常うまくいくのは、DBでnullを許可するように外部キー列を設定することです-それはあなたのAdvertId列になりますが、あなたがアイデンティティを使用しているので、それがあなたの場合にうまくいくかどうかはわかりません。NHibernateが行うことは、1つのクエリですべてをINSERTしてから、子テーブルの外部キー列を親テーブルの正しいIDに更新することです。多分それはあなたの場合にもうまくいくでしょう。

これが役立つかもしれないいくつかの同様の質問です:流暢なNHibernateで1対多にカスケード挿入

于 2012-06-01T16:52:11.770 に答える