Search code examples
subsonicsubsonic3subsonic-active-record

Saving record in Subsonic 3 using Active Record


I'm having trouble saving a record in Subsonic 3 using Active record. I've generated my objects using the DALs and tts and everything seems fine because the following test passes. I think that my connection string is correct or the generation wouldn't have succeeded.

[Test]
        public void TestSavingAnEmail()
        {
            Email testEmail = new Email();
            testEmail.EmailAddress = "[email protected]";
            testEmail.Subscribed = true;
            testEmail.Save();
            Assert.AreEqual(1, Email.All().Count());
        }

On the live side, the following code fails:

protected void btEmailSubmit_Click(object sender, EventArgs e)
        {
            Email email = new Email();
            email.EmailAddress = txtEmail.Text;
            email.Subscribed = chkSubscribe.Checked;
            email.Save();
        }

with a message of: Need to specify Values or a Select query to insert - can't go on! at the following line repo.Add(this,provider); line in my ActiveRecord.cs:

public void Add(IDataProvider provider){


            var key=KeyValue();
            if(key==null){
                var newKey=_repo.Add(this,provider);
                this.SetKeyValue(newKey);
            }else{
                _repo.Add(this,provider);
            }
            SetIsNew(false);
            OnSaved();
        }

Am I doing something horribly wrong here? The save and add methods have parameterless overloads that I thought were safe to use. Do I need to pass a provider? I've googled around for this for a while and was unable to come up with anything specific to my situation. Thanks in advance for any kind of answer.

The schema for the table is:

USE [xxxx]
GO
/****** Object:  Table [dbo].[Emails]    Script Date: 03/11/2010 13:15:08 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Emails](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [V_EmailAddress] [varchar](100) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
    [B_Subscribed] [bit] NOT NULL,
    [DT_CreatedOn] [datetime] NOT NULL,
    [DT_ModifiedOn] [datetime] NOT NULL,
 CONSTRAINT [PK_Emails] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

GO
SET ANSI_PADDING OFF

There is only 1 warning during generation and that is

Multiple template directives were found in the template. All but the first one will be ignored. Multiple parameters to the template directive should be specified within one template directive.

Settings.ttinclude


Solution

  • The select error you're seeing is SubSonic trying to pull out the newly-created PK, and it can't. So, be sure you have a Primary Key defined for your table. Next - make sure it's set to Auto Increment :).

    If that doesn't do it - kick up SQL Profiler and see what's happening. Also - if you could put the schema of your table here so I could see it, that would be helpful (just edit your message).