4

The problem occurs with the creation of cascading foreign keys using the following Models, where only one Model (UserAddition) knows the other (User) and there is no possibility to add a UserAddition property to the User class:

class User {
    public virtual Guid Id { get; set; }
    // Other fields of no relevance
}

class UserAddition {
    public virtual Guid Id { get; set; }
    public virtual User RemoteUser {get; set; }
    public virtual string AdditionalData {get; set; }
}

The generated SQL Table for UserAddition should have an foreign key to User which is set to ON DELETE CASCADE (the setting of ON UPDATE is not important).

When using the following mapping class, the foreign key is always set to "No Action", even though it's specified otherwise in the mapping. Am I missing something?

public class UserAdditionMapping : ClassMap<UserAddition>
{
    public TrainerToEmployeeMapping()
    {
        this.Id(x => x.Id);
        this.References(x => x.RemoteUser).ForeignKey().Cascade.All();
    }
}

The Database in use is an Microsoft SQL Server 11.

Thanks.

Fionn
  • 10,975
  • 11
  • 54
  • 84
  • Probably there is a missing link between the mappings. Have you already looked at http://stackoverflow.com/questions/4017901/fluent-nhibernate-cascade-delete-not-working – Mario Fraiß Feb 16 '14 at 22:34
  • As I stated above the User can not have a link to the UserAddition - only the UserAddition can have a User field - I am searching for a solution where I don't have to modify the User class. – Fionn Feb 16 '14 at 22:38
  • http://stackoverflow.com/a/7737697/40822 – dotjoe Feb 17 '14 at 01:59
  • I think you may need to generate an alter table SQL script that runs after you generate the schema – Rippo Feb 17 '14 at 07:55

2 Answers2

1

The answer is here NHibernate mapping not adding ON DELETE CASCADE option to foreign key reference. A cite:

NHibernate can only generate on delete cascade constraints on inverse collections.

A code snippet from NHibernate.Mapping.Collection:

public virtual void Validate(IMapping mapping)
{
    if (Key.IsCascadeDeleteEnabled && (!IsInverse || !IsOneToMany))
    {
      throw new MappingException(string.Format(
          "only inverse one-to-many associations may use on-delete=\"cascade\": {0}", Role));
    }
 ...

And then, in fluent, you'd have the mapping like this:

HasMany(x => x.UserAdditions)
   ...
   // the setting
   .ForeignKeyCascadeOnDelete()

But it would be on the inverse end, and would require to change the User class. I do understand that this is what you do not want (as stated above), but this is only think you can get out of the box...

Community
  • 1
  • 1
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
0

You can Try this:

this.References(x => x.RemoteUser).Column("YourColumnName").Cascade.All();

  • Doesn't work either, the Delete and Update Cascade Action is still generated as "No Action". – Fionn Feb 17 '14 at 01:05