Как удалить коллекцию с каскадированием в nhibernate? - PullRequest
1 голос
/ 30 декабря 2011

У меня есть это отображение

 public class CountryMapping : ClassMap<Country>
    {
        public CountryMapping()
        {
            Id(x => x.Id).GeneratedBy.GuidComb();
            Map(x => x.Name).Not.Nullable().NvarcharWithMaxSize();
            HasMany(x => x.Cards).Cascade.Delete().Inverse();
        }
    }

      public class CardMapping : ClassMap<Card>
    {
        public CardMapping()
        {
            Id(x => x.Id).GeneratedBy.GuidComb();
            Map(x => x.Name).Not.Nullable().NvarcharWithMaxSize(); ;
            References(x => x.Country).Not.Nullable();
            HasMany(x => x.RewardTiers).Cascade.All();
        }
    }

Теперь я хочу удалить страну. Если вы удалите страну, все карты должны быть удалены. Следует удалить все награды.

nhibernateRepo.Load<Country>(countryId);
nhibernateRepo.Delete<Country>(country);
unitOfWork.Commit();

Когда я это сделаю. Я получаю следующую ошибку.

NHibernate.Exceptions.GenericADOException was caught
  Message=could not delete collection: [Domain.Card.RewardTiers#7abaade7-4653-456f-8840-9fc700fa949b][SQL: UPDATE [RewardTier] SET Card_id = null WHERE Card_id = @p0]
  Source=NHibernate
  SqlString=UPDATE [RewardTier] SET Card_id = null WHERE Card_id = @p0
  StackTrace:
       at NHibernate.Persister.Collection.AbstractCollectionPersister.Remove(Object id, ISessionImplementor session)
       at NHibernate.Action.CollectionRemoveAction.Execute()
       at NHibernate.Engine.ActionQueue.Execute(IExecutable executable)
       at NHibernate.Engine.ActionQueue.ExecuteActions(IList list)
       at NHibernate.Engine.ActionQueue.ExecuteActions()
       at NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session)
       at NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event)
       at NHibernate.Impl.SessionImpl.Flush()
       at NHibernate.Transaction.AdoTransaction.Commit()
       at CCRecomendator.Framework.Data.UnitOfWork.Commit() in UnitOfWork.cs:line 52
       at CCRecomendator.Framework.Services.CountryService.DeleteCountry(Guid countryId) in CountryService.cs:line 157
  InnerException: System.Data.SqlClient.SqlException
       Message=Cannot insert the value NULL into column 'Card_id', table 'cc.dbo.RewardTier'; column does not allow nulls. UPDATE fails.
The statement has been terminated.
       Source=.Net SqlClient Data Provider
       ErrorCode=-2146232060
       Class=16
       LineNumber=1
       Number=515
       Procedure=""
       Server=(local)
       State=2
       StackTrace:
            at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
            at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
            at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
            at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
            at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
            at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
            at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
            at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)
            at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
            at NHibernate.AdoNet.AbstractBatcher.ExecuteNonQuery(IDbCommand cmd)
            at NHibernate.Persister.Collection.AbstractCollectionPersister.Remove(Object id, ISessionImplementor session)
       InnerException: 

Почему он пытается выполнить обновление после удаления?

1 Ответ

1 голос
/ 30 декабря 2011

Он пытается сделать обновление, потому что думает, что Card является «владельцем» ассоциации Страна-> Карты, и поэтому, когда Страна удаляется, NH считает, что ему необходимо обнулить ссылки на Страну. Это вызвано модификатором обратного отображения. Согласно документации для Inverse:

Обратное владение этой сущностью. Сделайте другую сторону Отношения, ответственные за сохранение.

Попробуйте удалить Inverse из HasMany(x => x.Cards).Cascade.Delete().Inverse();

...