views:

172

answers:

3

I'm sure I'm missing the obvious answer here, but could use a hand. I'm new to SubSonic and using version 3. I've got myself to the point of being able to query and insert, but I'm stuck with how I would get the value of the identity column back after my insert. I saw another post that mentioned Linq Templates. I'm not using those (at least I don't think I am...?)

TIA

... UPDATE ...

So I've been debugging through my code watching how the SubSonic code works and I found where the indentity column is being ignored. I use int as the datatype for my ID columns in the database and set them as identity. Since int is a non-nullable data type in c# the logical test in the Add method (public void Add(IDataProvider provider)) that checks if there is a value in the key column by doing a (key==null) could be the issue. The code that gets the new value for the identity field is in the 'true path', since an int can't be null and I use ints as my identity column data types this test will never pass. The ID field for my object has a 0 in it that I didn't put there. I assume it's set during the initialization of the object. Am I off base here? Is the answer to change my data types in the database?

Another question (more a curiosity). I noticed that some of the properties in the generated classes are declared with a ? after the datatype. I'm not familiar with this declaration construct... what gives? There are some declared as an int (non key fields) and others that are declared as int? (key fields). Does this have something to do with how they're treated at initialization?

Any help is appreciated!

--BUMP--

A: 

Can't help you much with the first part of your question. Probably you should create a T4 template for that, as explained here:

http://stackoverflow.com/questions/1576451/how-can-i-get-the-identity-column-value-associated-with-a-subsonic-3-linqtemplate

The "?" that you find after the int declaration refers to a nullable type:

http://msdn.microsoft.com/en-en/library/1t3y8s4s(VS.80).aspx

It basically means that the property can be null.

mamoo
A: 

This works for me, I'm using exactly the same setup:

Account account = new Account();
account.EmailAddress = emailAddress;
account.Identity = identifier;
account.IsActive = true;
account.Save();

int accountId = account.AccountId; // AccountId being an identity column.

No error handling in this example, but you get my drift.

Junto
I agree that what I'm doing should work, but when it hits this line in the add method ( if(key==null) ) where it checks to see if the key value is null, the key variable is always 0, regarless if it is a new record or not.
A: 

In addition to my previous answer; an integer value cannot be null. It is an integer because the database column is a primary key, and therefore it should not be null by definition. The default value for a non-nullable integer is 0. See default Values in C#

Mamoo's reference to nullable types is also worth referring to. Your unit test should therefor test against 0 for a failure or greater than 0 for a pass.

Junto
Thanks Junto, the problem I'm having is with the logic being used to determine if the record is new and a new key needs to be generated. If you go to any of your generated classes and find the Add method with this signature - public void Add(IDataProvider provider) - and follow the logic there you'll see that it retrieves the key value for the class, compares it to null and if it is (which will never happen because it's a non nullable int) it generates a new key value for the record. If not, it keeps the 0 value and fails on insert. I'm sure I have the latest build, am I missing something?
Is it maybe to support non-integer primary keys? Default value of string is null. I have the same build as you and I can see what you mean. The key is never null in the case of an integer: var key=KeyValue(); if(key==null){ var newKey=_repo.Add(this,provider); this.SetKeyValue(newKey); }else{ _repo.Add(this,provider); }
Junto
By the way, I had similar issues today (i.e. failed insert). I realized that I had forgotten to set the identity insert on the primary key column of one of my tables. Even after I re-ran the custom tool, the the changes were not picked up. I had to delete all of the generated Subsonic code and templates, before closing and reopening the solution for good measure. After copying the templates back into the solution the identity insert started working.
Junto