Deleting records (NOT content records) with one to many relationship

Topics: Customizing Orchard, Writing modules
Jul 13, 2012 at 10:48 AM

Hi

I have the following migration.cs for my module:

SchemaBuilder.CreateTable("CorporateEmailRecord", table =>
                table
                .Column<int>("Id", col => col.PrimaryKey().Identity())
                .Column<string>("Alias")
                .Column<string>("EmailAddress")
                .Column<int>("DisplayOrder")
                .Column<string>("DisplayTitle")
                .Column<bool>("IsDefault"));
            
            SchemaBuilder.CreateTable("EmailMessageRecord", table =>
                table
                .Column<int>("Id", col => col.PrimaryKey().Identity())
                .Column<int>("CorporateEmailPartRecord_Id")
                .Column<string>("Sender")
                .Column<string>("Recipient")
                .Column<string>("Subject")
                .Column<string>("Body")
                .Column<string>("TitleAndName")
                .Column<string>("Address")
                .Column<string>("Telephones"));

Ie, CorporateEmailRecord has a one to many rel with EmailMessageRecord.

To delete a CorporateEmailRecord, I use a method in a service class:

 

public Tuple<stringstring> DeleteCorporateEmail(int id) 
        {
            var ce = GetCorporateEmail(id);
            var t = new Tuple<stringstring>(ce.Alias, ce.EmailAddress);
            _repositoryCepRecord.Delete(ce);
            return t;
        }

(The tuple is just used to get the data into my controller for display as a Notification).

My Controller action (HttpPost) is:

[HttpPostActionName("Delete")] 
        public ActionResult DeletePOST(int id)
        {
            var tuple = service.DeleteCorporateEmail(id);
            _notifier.Add(NotifyType.Information, T(tuple.Item1 + " (" + tuple.Item2 + ") has been deleted!"));
            return RedirectToAction("Index");
        }

 

Problem:

Despite the notification displaying, the record does not get deleted.

No errors are returned in the IDE.  However, in the log, I get:

2012-07-13 07:17:35,180 [10] NHibernate.AdoNet.AbstractBatcher - Could not execute command: UPDATE Wingspan_CorporateEmails_EmailMessageRecord SET CorporateEmailRecord_Id = null WHERE CorporateEmailRecord_Id = @p0
System.Data.SqlServerCe.SqlCeException (0x80004005): The column name is not valid. [ Node name (if any) = ,Column name = CorporateEmailRecord_Id ]

This shows that the problem is with nHibernate trying to delete any child records.

 

Questions:

So what should I do?

How can I have the one to many relationship and delete records?

What changes would I need to make to my migrations.cs class?

Coordinator
Jul 13, 2012 at 10:58 AM

Your column is named CorporateEmailPartRecord_Id. It should be CorporateEmailRecord_Id.

Jul 13, 2012 at 11:20 AM
Edited Jul 13, 2012 at 12:09 PM

Many thanks Bertrand.

Now then, which of my molars am I going to shoot in the root?  And with which barrel?

Why do I think resharper will refactor hard coded strings?

Coordinator
Jul 13, 2012 at 11:47 AM

Maybe because it sometimes does... If Orchard is successful enough, one day it will ;)

Jul 13, 2012 at 12:08 PM

With the effort I am putting into getting to grips with Orchard, I seriously hope Orchard "one day will"!

Coordinator
Jul 13, 2012 at 12:10 PM

I mean that maybe someday Resharper becomes aware of Orchard patterns and handles its refactoring...

Jul 13, 2012 at 12:24 PM

Sorry, I may have been misunderstood.  I really like Orchard and hope it becomes successful enough not just for Resharper, but also to warrant ongoing development by your good selves.

I am still too green to help, but no doubt will add a few modules soon or later.

Many thanks.

Coordinator
Jul 13, 2012 at 12:25 PM

Cool.

Developer
Jul 13, 2012 at 1:00 PM
Edited Jul 13, 2012 at 1:01 PM

@awrigley: If you want to explicitly mark some related record(s) to be deleted when parent record gets deleted - mark the child property with [CascadeAllDeleteOrphan]. In your case you should try adding the code below to your CorporateEmailRecord class (remember to initialize the collection to empty one in ctor).

[CascadeAllDeleteOrphan]
public virtual IList<EmailMessageRecord> Messages { get; set; }

Jul 13, 2012 at 1:56 PM

Thanks Piotr