1

極端な初心者の質問。私のデータベース(SQL Server)は、私の関係の削除をカスケードするように設定されているので、親エンティティを削除すると、すべての子も同様に削除されます(ON DELETE CASCADE)。私はこれを私の自動で実行されるFluent NHibernateの設定に反映させたい。しかし、私が子エンティティを削除しようとすると、NHibernateは代わりに関係キーをNULLに設定しようとしています。Automapperを使用してカスケード削除を使用してFluent NHibernate one-to-manyを設定する

データベースは超簡単です:( "1" のため--、 "多く" のための-<

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ではデフォルトでカスケードしません。あなたが影響されることが必要な他の関係の

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

同様に:このようなcodeGroup.Codes関係にカスケード設定してください。ただ、最後に ".Inverse()" という必要:OP編

。この質問に関連する:key-many-to-one and key-property association: nhibernate won't DELETE items from set

+0

'AllDeleteOrphan()'は 'カスケード'のメンバーではありません。おそらく '' All() '"ですか? – roufamatic

+0

あなたはそうです。 'AllDeleteOrphan'は* one-to-many *のみのため、' All'はここに行きます。 – NOtherDev

+0

いいえ、これは動作していません - 'テーブルCodeGroupからの関連付けはマップされていないクラスを参照しています:System.Collection.Generic.IList''1 [[MyNamespace.Code、...]]' – roufamatic

1

あなたはthis issueを打つかもしれません。 3.2.0Beta2以降を実行している場合を除き、削除をカスケードする場合は、次のいずれかを実行する必要があります。

  1. 子のFKをNULLにすることができます。または
  2. 逆の関係を作成します(つまり、子には親にマップされた参照が必要です)。

チケットからわかるように、これは非常に最近修正されています。

関連する問題