Fluent NHibernate делает обновление после вставки в составной ключ - PullRequest
1 голос
/ 05 января 2011

Я использую Fluent NHibernate для сопоставления составного ключа. Мне нужно, чтобы дочерний объект получал вновь вставленный родительский ключ при создании родителя. Это работает, но NHibernate выполняет вставку дочернего элемента, а затем обновляет один из идентификаторов составного ключа дочернего элемента.

Отношения сущностей следующие:

1) Модель (родительская) - имеет много весовых коэффициентов.
2) FactorWeight (ребенок) имеет один фактор.
3) Факторы могут иметь разные веса для каждой модели.

Так как модели имеют много факторов, а фактор может иметь разные весовые коэффициенты для разных моделей, сущность FactorWeight требуется с составным ключом ModelID и FactorID.

Модель:

    public virtual int ID { get; set; }  
    public virtual IList<FactorWeight> FactorWeights { get; set; }  
    public virtual string Name { get; set; }    

Фактор

    public virtual int ID { get; set; }  
    public virtual string Name { get; set; }  

FactorWeight:

    public virtual Factor Factor { get; set; }  
    public virtual Model Model { get; set; }  
    public virtual decimal Weight { get; set; }  

Отображения следующие:

Модель:

public void Override(AutoMapping<Model> mapping)
{
 mapping.Id(x => x.ID);
 mapping.Map(x => x.Name);

 mapping.HasMany(x => x.FactorWeights)
    .KeyColumn("ModelID");
}

FactorWeights

public void Override(AutoMapping<FactorWeight> mapping)
{
 mapping.CompositeId()
           .KeyReference(factorWeight => factorWeight.Model, "ModelID")
           .KeyReference(factorWeight => factorWeight.Factor, "FactorID");

 mapping.Map(factorWeight => factorWeight.Weight);
}

Я использую следующий код для создания FactorWeight в объекте Model:

Model.FactorWeights.Add(new FactorWeight {Factor = factor, Weight = weighting, Model = Model });

Для сохранения сущности (где модель передается методу) используется следующее:

public void CreateEntity(object entity)
{
 HibernateConfiguration.Session.Transaction.Begin();
 NHibernateConfiguration.Session.Save(entity);   
 NHibernateConfiguration.Session.Transaction.Commit();
}

Объект модели сохраняется без ошибок, а также FactorWeight. Проблема в том, что SQL Profiler показывает обновление в столбце FactorWeight.ModelID сразу после вставки. NHibernate обновляет FactorWeight.ModelID с недавно вставленным ModelID, который уже присутствовал во вставке.

SQl Profiler Trace:

exec sp_executesql N'INSERT INTO [FactorWeight] (Weight, ModelID, FactorID) VALUES (@p0, @p1, @p2)',N'@p0 decimal(1,0),@p1 int,@p2 int',@p0=1,@p1=56,@p2=1  
exec sp_executesql N'UPDATE [FactorWeight] SET ModelID = @p0 WHERE ModelID = @p1 AND FactorID = @p2',N'@p0 int,@p1 int,@p2 int',@p0=56,@p1=56,@p2=1

Я предполагаю, что это проблема с отображением составного ключа.

Я использую версию 2.1.2.400 NHibernate и версию 1.1.0.685 FluentNHibernate.

Спасибо.

1 Ответ

1 голос
/ 05 января 2011

Хорошо, я думаю, что мне нужно улучшить свои навыки поиска в Google ... нашел ответ здесь: Возможно ли отменить обновление после вставки в NHibernate? .

Оказывается, мне нужно было добавить Inverse () к отображению на родительском элементе. Добавлено следующее и проблема решена:

    mapping.HasMany(x => x.FactorWeights)
    .KeyColumn("ModelID")
    .Inverse();  

" Inverse сообщает родителю, что ребенок отвечает за поддержание отношений, предотвращая тем самым дополнительное обновление " - по ссылке выше.

...