1

극단적 인 초보자 질문. 부모님 엔티티를 삭제하면 모든 자식도 삭제됩니다 (ON DELETE CASCADE) 그래서 내 데이터베이스 (SQL Server) 내 관계에 대한 삭제를 계단식으로 설정했습니다. 나는 이것이 자동으로 실행 된 Fluent NHibernate 설정에 반영되기를 바랍니다. 그러나 자식 엔터티를 삭제하려고 할 때 NHibernate는 대신 관계 키를 NULL로 설정하려고 시도합니다.Automapper를 사용하여 계단식 삭제로 Fluent NHibernate 일대 다 설정하기

데이터베이스는 슈퍼 간단하다

User ---<UserCode>--- Code >--- CodeGroup 

나는 CodeGroup을 삭제

의 삭제가 CodeUserCode까지 단계적으로해야한다 ("다"에 대한 "하나"에 대한 --, -<). 코드를 삭제하면 UserCode으로 캐스케이드되어야하지만 CodeGroup은 변경되지 않습니다.

내 엔티티 (명확성을 위해 제거 특성) :

var _sessionFactory = 
    Fluently.Configure() 
    .Database(FluentNHibernate.Cfg.Db.MsSqlConfiguration.MsSql2005.ConnectionString(c => c.FromConnectionStringWithKey("db")).ShowSql()) 
    .Cache(csb => csb.UseQueryCache()) 
    .Mappings(m => 
     m.AutoMappings.Add(
     AutoMap.AssemblyOf<Code>(new AutomappingConfiguration()) 
     .Override<User>(map => map.HasManyToMany(u => u.FoundCodes).Table("UserCode")) 
     .Override<Code>(map => map.HasManyToMany(c => c.UsersWithCode).Inverse().Table("UserCode")) 
     .Conventions.Add(new CustomForeignKeyConvention()))) 
    .BuildSessionFactory()) 

을하지만이 작업을 수행 할 때 :

public class User { 
    public virtual IList<Code> FoundCodes { get; private set; } 
} 
public class Code { 
    public virtual IList<User> UsersWithCode { get; private set; } 
    public virtual CodeGroup CodeGroup { get; set; } 
} 
public class CodeGroup { 
    public virtual IList<Code> Codes { get; private set; } 
} 

다음은 SessionFactory를 보이는 방법

using (var tx = _db.BeginTransaction()) 
{ 
    var codeGroup = _db.Load<CodeGroup>(id); 
    _db.Delete(codeGroup); 
    tx.Commit(); 
} 

나는이 얻을 :

could not delete collection: [MidnightRoseRace.Data.Entities.CodeGroup.Codes#8] 
    [SQL: UPDATE [Code] SET CodeGroupId = null WHERE CodeGroupId = @p0] 
Cannot insert the value NULL into column 'CodeGroupId', table 'MyNamespace.dbo.Code'; 
    column does not allow nulls. UPDATE fails. 
The statement has been terminated. 

삭제 작업은 삭제할 수 없지만 null이 아닌 외부 키를 null로 설정하려고합니다. 무슨 일이야?

답변

2

삭제는 NHibernate에서 기본적으로 계단식으로 정렬되지 않습니다. 이 같은 codeGroup.Codes 관계에 계단식으로 설정 : 당신이 영향을받을 필요가 다른 관계

AutoMap.AssemblyOf<Code>(new AutomappingConfiguration()) 
    // existing overrides 
    .Override<CodeGroup>(
     map => map.HasMany(c => c.Codes).Cascade.AllDeleteOrphan().Inverse()) 

와 유사합니다.

OP로 편집 : 끝에 ".Inverse()"가 필요합니다. 이 질문과 관련 : key-many-to-one and key-property association: nhibernate won't DELETE items from set

+0

'AllDeleteOrphan()'은 (는)'계단식 '의 구성원이 아닙니다. 아마도''All()' "을 의미할까요? – roufamatic

+0

네 말이 맞아. AllDeleteOrphan은 * 일대 다 * 전용이고, All은 여기에 있습니다. – NOtherDev

+0

아니요,이 코드가 작동하지 않습니다. -'CodeGroup 테이블의 연관은 매핑되지 않은 클래스를 참조합니다. System.Collection.Generic.IList''1 [[MyNamespace.Code, ...]] ' – roufamatic

1

this issue 일 가능성이 있습니다. 3.2.0Beta2 이상을 실행하지 않는 한 삭제를 계단식으로 연결하려면 다음 중 하나를 수행해야합니다.

  1. 자녀의 FK를 null로 설정할 수 있습니다. 또는
  2. 반비례 관계를 만듭니다. 즉, 자식에는 부모에 대한 매핑 된 참조가 있어야합니다.

티켓에서 알 수 있듯이 이것은 매우 최근에 수정 된 오랜 (많은 upvoted) 문제입니다.