Вопрос по nhibernate – Свободное отображение NHibernate один-ко-многим

8

У меня есть следующие 2 класса:

Advert

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; }

В БД моя таблица AdvertImages имеет FK "AdvertId". которая относится к таблице Adverts, которая имеет PK "Id".

Это отображение «один ко многим», в котором одно объявление может иметь много изображений.

Мои беглые отображения NHibernate (отредактированные для краткости):

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 свойство (рекламы) сList<AdvertImage>.

Когда я продолжаю настаиватьAdvert Для объекта БД я бы хотел, чтобы AdvertImages был вставлен в их таблицу AdvertImages, но из-за связи между двумя таблицами мне нужно, чтобы вставка Advert выполнялась первой, так как генерируется PK Id, который затем можно вставить в таблице AdvertImages. (Когда я создаю свой список AdvertImage, я заполняю свойство Filename, но, очевидно, у меня нет нового AdvertId на этом этапе, поэтому я хочу, чтобы он заполнялся, когда реклама сохраняется в БД).

Я попытался поэкспериментировать с различными настройками Inverse () и Cascade, но пока не удалось. Может кто-нибудь помочь, пожалуйста?

Ваш Ответ

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();
    }
}

Мои сущности обычно содержат методы Add и Remove для двунаправленных отношений один-ко-многим, например:

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

    public virtual void AddImage(AdvertImage newImage)
    {
        newImage.Advert = this;
        AdvertImages.Add(newImage);
    }
}
Спасибо Cole W, и хороший совет о методах Add и Remove. marcusstarnes
2

пробуя различные типы картирования. Затем я обнаружил, что мои отображения были в порядке, и на самом деле мне нужно было обернуть мой сеанс в транзакцию и использовать метод Commit () после метода session.SaveOrUpdate ().

using(var session = sessionFactory.OpenSession()) 
using(var tx = session.BeginTransaction()) 
{ 
// execute code that uses the session 
tx.Commit(); 
}
спасибо .. сэкономил много времени, копаясь вокруг этой проблемы
1

ия пустых значений в БД - это будет ваш столбец AdvertId, но я не уверен, будет ли это работать в вашем случае, так как вы используете идентичность. NHibernate делает INSERT для всех одним запросом, а затем обновляет столбец внешнего ключа дочерней таблицы, указав правильный идентификатор родительской таблицы. Может быть, это будет работать и в вашем случае.

Вот несколько похожих вопросов, которые могут помочь:Каскадная вставка на один ко многим с беглым NHibernate

@KomengeMwandila Хотя в ответе на вопрос, который я связал, не используется Fluent NHibernate, этот вопрос есть. Кроме того, Fluent NHibernate не добавляет сюда ничего нового. Он просто предоставляет другой интерфейс для отображения NHibernate. Как только вы поймете, как работает сопоставление, вы можете применить его к Fluent NHibernate, сопоставлению XML, сопоставлению по коду ...
Эта ссылка, которую вы включили, не имеет смысла, так как не имеет ничего общего сFluent NHibernate.

Похожие вопросы