Question

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 = "newemail@test.com";
            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

Was it helpful?

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).

OTHER TIPS

This should generally work.

A few possible points of failure come to my mind:

  • Are you using a standard MSSQL provider (database)?
  • Did you provide a connection string in the web.config (website) or app.config (class library project)?
  • Did you set a primary key column in the database?
  • Is your table using multiple primary key columns? Subsonic can't handle that. Use a single artificial ID column (uniqueidentifier or int) in that case.
  • If the primary key value is an integer field: does it auto-increment the id values? Otherwise you'd have to set the primary key value on your email object before saving it.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top