2010-01-08 5 views
1

Я не уверен, если это правильное поведение или что-то сделано неправильно с моей стороны:Почему NHibernate сначала вставляет, а затем обновляет элемент коллекции?

Я получил очень простой родитель-потомок

public class SubmittedBatch 
{ 
    public virtual Guid Id { get; set; } 
    public virtual IList<SubmittedBatchParameter> Parameters { get; private set; } 
} 

public class SubmittedBatchParameter 
{ 
    public virtual string Value { get; set; } 
} 

И FluentNH он сконфигурирован, как:

mapping.HasMany<SubmittedBatchParameter>(sb => sb.Parameters).Cascade.All(); 

я сделать что-то простое, как добавить новый элемент в Parameters коллекции, а затем вызвать SaveOrUpdate на родительский элемент.

Глядя на след операторов SQL я получаю вставку:

INSERT INTO [SubmittedBatchParameter] 
      (Value) 
VALUES  ('Disabled' /* @p0 */) 
select SCOPE_IDENTITY() 

а затем обновление:

UPDATE [SubmittedBatchParameter] 
SET SubmittedBatch_id = '209971b7-c311-46bd-b989-9cf80113654c' /* @p0_0 */ 
WHERE Id = 39 /* @p1_0 */ 

Почему не NH просто делать Insert с также Guid указано ? Правильно ли это, или я делаю что-то неправильно?

Спасибо Simone

ответ

5

Вы не отображается обратный родительские отношения в явном виде. Поэтому единственный способ, которым NHibernate знает сохранить значение SubmittedBatch_id, это когда вы сохраняете объект parent. Он не может одновременно сохранять оба объекта, поэтому он должен сохранять дочерний элемент, а затем, когда он сохраняет родителя, сохраните связь.

Фактически, даже если вы должны были отображать оба направления отношений, вам все равно нужно указать, что является «мастером», обозначив другое как «обратное» отношение. Затем поле обновляется с сохранением главной стороны.

Итак, если вы должны были сопоставить свойство SubmittedBatch в классе SubmittedBatchParameter, назовите это как «мастер» (т.е. установите сопоставление коллекции как обратное, используя .Inverse in Fluent), а затем установите это, когда вы добавляете параметр в пакет, тогда вы увидите только вставку, которую вы ожидаете.

Вот что я имею в виду:

public class SubmittedBatch 
{ 
    public virtual Guid Id { get; set; } 
    public virtual IList<SubmittedBatchParameter> Parameters { get; private set; } 
} 

public class SubmittedBatchParameter 
{ 
    public virtual SubmittedBatch SubmittedBatch { get; set; } 
    public virtual string Value { get; set; } 
} 

Тогда в отображении ребенка:

HasMany<SubmittedBatchParameter>(sb => sb.Parameters).Inverse(); 

и в родительском отображения:

References(sbp => sbp.SubmittedBatch); 
+0

Да, точно ... мне не нужно ссылка revere для моего кода, но, вероятно, я должен добавить его в любом случае, чтобы заставить NH работать. Спасибо – CodeClimber

+0

Если SubmittedBatch_id не является нулевым, как я подозреваю, это должно быть, тогда вам нужно будет сделать это для его работы. Если значение NULL, то это просто вопрос о том, чтобы сделать это в меньшем количестве операторов SQL. :) –

Смежные вопросы