views:

499

answers:

5

hello, how would i get the primary key id number from a Table WITHOUT making a second trip to the database in LINQ To SQL?

right now, i submit the data to a table, and make another trip to figure out what id was assigned to the new field (in an auto increment id field).

also, seond part of my question is: i am always careful to know the id of a user thats online because i'd rather call their information in various tables using their id as opposed to using a guid or a username, which are all long strings... i do this because i think that SQL Server doing a numeric compare is much (tentative use of the word 'much') more efficient than doing a username (string) or even a guid (very long string) compare... my questions is, am i more concerned than i should be? is the pref. difference worth always keeping the userid (int32) in say, session state?

A: 

In T-SQL, you could use the OUTPUT clause, saying:

INSERT table (columns...)
OUTPUT inserted.ID
SELECT columns...

So if you can configure LINQ to use that construct for doing inserts, then you can probably get it back easily. But whether LINQ can get a value back from an insert, I'll let someone else answer that.

Rob Farley
i dont know how to write sql procedures in sql lang. but if i could im pretty sure linq can map to sql stored procedures in it's .dbml file designer, so it should be able to get return values, probably only if you do the entire INSERT using t-sql... otherwise i am unsure as well.
Erx_VB.NExT.Coder
i dont think InsertOnSubmit or Submit as a return value thats relevant to our needs.
Erx_VB.NExT.Coder
+1  A: 

Linq to SQL automatically sets the identity value of your class with the ID generated when you insert a new record. Just access the property. I don't know if it uses a separate query for this or not, having never used it, but it is not unusual for ORMs to require another query to get back the last inserted ID.

Two ways you can do this independent of Linq To SQL (that may work with it):

1) If you are using SQL Server 2005 or higher, you can use the OUTPUT clause:

Returns information from, or expressions based on, each row affected by an INSERT, UPDATE, or DELETE statement. These results can be returned to the processing application for use in such things as confirmation messages, archiving, and other such application requirements. Alternatively, results can be inserted into a table or table variable.

2) Alternately, you can construct a batch INSERT statement like this:

insert into MyTable
(field1)
values
('xxx');
select scope_identity();

which works at least as far back as SQL Server 2000.

RedFilter
hi orbMan, if linq to sql auto updated the id column of a class after a SubmitChanges, that would be fantastic, would anyone be able to confirm this?
Erx_VB.NExT.Coder
@Erx_VB.NExT.Coder: It will update the id column on inserts, if you tell it to. By default, if your id column is of type int, it will automatically be set to "generated on insert", if it is of type guid, then you have to change the default to "generate on insert". You do that from the Linq 2 SQL designer.
Egil Hansen
+3  A: 

Unless you are doing something out of the ordinary, you should not need to do anything extra to retrieve the primary key that is generated.

When you call SubmitChanges on your Linq-to-SQL datacontext, it automatically updates the primary key values for your objects.

Regarding your second question - there may be a small performance improvement by doing a scan on a numeric field as opposed to something like varchar() but you will see much better performance either way by ensuring that you have the correct columns in your database indexed. And, with SQL Server if you create a primary key using an identity column, it will by default have a clustered index over it.

David Hall
hello, thanks, your right its auto incremented during SubmitChange, thats not a problem - i need to keep this number/id to use it to call other records really, thats the only reason why i want it in session state.
Erx_VB.NExT.Coder
+7  A: 

If you have a reference to the object, you can just use that reference and call the primary key after you call db.SubmitChanges(). The LINQ object will automatically update its (Identifier) primary key field to reflect the new one assigned to it via SQL Server.

Example (vb.net):

  Dim db As New NorthwindDataContext
  Dim prod As New Product
  prod.ProductName = "cheese!"
  db.Products.InsertOnSubmit(prod)
  db.SubmitChanges()
  MessageBox.Show(prod.ProductID)

You could probably include the above code in a function and return the ProductID (or equivalent primary key) and use it somewhere else.

EDIT: If you are not doing atomic updates, you could add each new product to a separate Collection and iterate through it after you call SubmitChanges. I wish LINQ provided a 'database sneak peek' like a dataset would.

calico-cat
@calico: thanks mate that was explained perfectly, also refreshing to see some vb code up here every now and then, given u upvote and accept answer so now you can start downvoting peeps :)
Erx_VB.NExT.Coder
A: 

Calling a stored procedure from LINQ that returns the ID as an output parameter is probably the easiest approach.

RickNZ