1

Посмотрите на лица -Обновление ребенка вместо того, чтобы удалить его

class Person 
{ 
    int id { get; set; }; 
    IList<PersonAddress> Addresses { set; get; } 
    ... 
} 

Теперь при обновлении человека из пользовательского интерфейса, если я просто удалить некоторые адреса из списка адрес я палочка на самом деле удалить адрес записи из БД , в настоящее время это обновляет значение таблицы адресов personId = NULL и не удаляет запись адреса. Кто-нибудь знает как это сделать. может быть проблема с отображением.

Здесь я добавляю файл сопоставления всего Person.

public class PersonMappingOverride : IAutoMappingOverride<Person> 
{ 
    public void Override(AutoMapping<Person> mapping) 
    { 
     mapping.Schema(Schemas.Common); 
     mapping.Table("Person"); 

     mapping.Map(x => x.FirstName).Not.Nullable(); 
     mapping.Map(x => x.LastName).Not.Nullable(); 
     mapping.Map(x => x.DateOfBirth).Nullable(); 

     mapping.References(x => x.Title); 
     mapping.References(x => x.Ethnicity); 
     mapping.References(x => x.Language); 
     mapping.References(x => x.Religion); 
     mapping.References(x => x.Country); 
     mapping.References(x => x.Gender).Not.Nullable(); 

     mapping.References(x => x.LoginDetail); 

     mapping.HasMany(x => x.Addresses) 
      .ForeignKeyConstraintName("FK_PersonAddress_Person_PersonID") 
      .Where("DeletedDate is null") 
      .Cascade.AllDeleteOrphan() 
      .Cascade.SaveUpdate(); 

     mapping.HasMany(x => x.TelephoneNumbers) 
      .ForeignKeyConstraintName("FK_PersonTelephoneNumber_Person_PersonID") 
      .Where("DeletedDate is null") 
      .Cascade.AllDeleteOrphan() 
      .Cascade.SaveUpdate(); 

     mapping.HasMany(x => x.EmailAddresses) 
      .ForeignKeyConstraintName("FK_PersonEmailAddress_Person_PersonID") 
      .Where("DeletedDate is null") 
      .Cascade.AllDeleteOrphan() 
      .Cascade.SaveUpdate(); 

     mapping.References(x => x.Photograph); 

     mapping.References(x => x.Signature); 

     mapping.HasMany(x => x.Photographs) 
      .ForeignKeyConstraintName("FK_PersonPhotograph_Person_PersonID") 
      .Where("DeletedDate is null") 
      .Cascade.AllDeleteOrphan() 
      .Cascade.SaveUpdate(); 

     mapping.HasMany(x => x.Signatures) 
      .ForeignKeyConstraintName("FK_PersonSignature_Person_PersonID") 
      .Where("DeletedDate is null") 
      .Cascade.AllDeleteOrphan() 
      .Cascade.SaveUpdate(); 

     //mapping.HasMany(x => x.JobRoles) 
     // .ForeignKeyConstraintName("FK_PersonJobRole_Person_PersonID"); 
     mapping.HasMany(x => x.Skills) 
      .ForeignKeyConstraintName("FK_PersonSkill_Person"); 
     mapping.HasMany(x => x.SpokenLanguages) 
      .ForeignKeyConstraintName("FK_PersonSpokenLanguage_Person"); 
     mapping.HasMany(x => x.ForbiddenCentres) 
      .ForeignKeyConstraintName("FK_PersonForbiddenCentre_Person"); 
     mapping.HasMany(x => x.Availabilities) 
      .ForeignKeyConstraintName("FK_PersonAvailability_Person"); 
     mapping.HasMany(x => x.Qualifications) 
      .ForeignKeyConstraintName("FK_PersonQualification_Person"); 

     mapping.IgnoreProperty(x => x.PrimaryEmailAddress); 
     mapping.IgnoreProperty(x => x.WorkAddress); 
    } 
} 

Это для PersonAddress отображения:

public class PersonAddressMappingOverride : IAutoMappingOverride<PersonAddress> 
{ 
    public void Override(AutoMapping<PersonAddress> mapping) 
    { 
     mapping.Schema(Schemas.Common); 
     mapping.Table("PersonAddress"); 
     mapping.References(x => x.Person); 
     mapping.References(x => x.Address).Cascade.SaveUpdate().Not.Nullable(); 
     mapping.References(x => x.AddressType).Not.Nullable(); 
    } 
} 
+0

Это вопрос отображения поэтому, пожалуйста, выкладывает отображение также ta. – Rippo

+0

mapping.HasMany (х => x.Addresses) .ForeignKeyConstraintName ("FK_PersonAddress_Person_PersonID") .гд ("DeletedDate является нулевым") .Cascade.AllDeleteOrphan() .Cascade.SaveUpdate(); – sachin

+0

Это файл сопоставления для класса Person, который, как он выглядит, уже использует Cascade.AllDeleteOrphan() – sachin

ответ

2

EDIT: беглый отображение добавлено прилагается ниже

Давайте предположим, что ваше отображение с помощью <bag> выглядит следующим образом:

<bag name="address" > 
    <key column="PersonId" /> 
    <one-to-many class="Address"/> 
</bag> 

Это w orking, и инструктируя NHibernate поддерживать коллекцию address. Если в коллекцию добавлен новый объект, его столбец PersonId будет обновлен в соответствии с текущим Лицом. Если какой-либо адрес удален ... его столбец PersonId будет иметь значение null.

Если мы хотим больше, мы могли бы использовать каскадные:

<bag name="address" cascade="all-delete-orphan" 
    <key column="PersonId" /> 
    <one-to-many class="Address"/> 
</bag> 

В этом случае, мы не заботимся только об отношениях, но даже об элементах внутри коллекции. Проверьте это отображение для более подробной информации: 6.2. Mapping a Collection (небольшой экстракта):

(6) каскад (опционально - по умолчанию ни один) обеспечивает выполнение операции каскада для дочерних объектов

Теперь, когда мы удалить экземпляр адреса из коллекции, он также будет удален из состояния persistence. Но шаги, чтобы сделать это будет:

  1. адрес Update и установите PersonId в NULL
  2. Удалить адрес

Чтобы избежать этого, мы можем добавить еще одно отображение функции: обратное отображение. Таким образом, в случае, что адрес имеет отображение на лицо (многие к одному), мы можем использовать это отображение (см inverse="true"):

<bag name="address" cascade="all-delete-orphan" inverse="true"> 
    <key column="PersonId" /> 
    <one-to-many class="Address"/> 
</bag> 

Какой может быть отмечен как наиболее эффективными, так как все изменения будут выполненных непосредственно на элементах адреса (без промежуточных этапов)

ПРИМЕЧАНИЕ: только маленький цитат из 6.2:

Примечание: Большие сумки NHibernate с обратным значением = "ложные" неэффективны и их следует избегать; NHibernate не может создавать, удалять или обновлять строки по отдельности, поскольку нет ключа, который может использоваться для идентификации отдельной строки.

EDIT: беглое отображение

баз по картированию вы включены в этом вопросе, вы должны настроить отображения адреса таким образом:

... 
mapping.HasMany(x => x.Addresses) 
    .ForeignKeyConstraintName("FK_PersonAddress_Person_PersonID") 
    .Where("DeletedDate is null") 
    .Inverse() // this will cause the direct DELETE to be issued 
    .Cascade.AllDeleteOrphan() // this is the only Cascade which should be used 
    ; 
+0

Спасибо Ramdim за ваш ответ. Я проверю его и дам вам знать! – sachin

+0

Я видел, что у меня уже есть опция all-delete-orphan для cascad. – sachin

+0

Как я уже видел в ваших комментариях под вашим вопросом, проблема может быть в неправильном каскадном сопоставлении. Вы используете Cascading для вашего сопоставления адресов-персонажей Person: 'Cascade.AllDeleteOrphan() .Cascade.SaveUpdate();' Это неправильно, я бы сказал, потому что последний выигрывает и перевыполняет предыдущий. Удалите последний 'SaveUpdate()' и оставьте только 'Cascade.AllDeleteOrphan()'. Теперь все должно работать как ожидалось –

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