I have a little question.
Short description of the project: I'm working on a little API project written in C#. Inside this project I'm using the onion architecture, in short it's something like Controller -> Service -> Repository.
I have an Account controller, which manages create & update User and beside this I have a databas ewith the following tables:
User, Password, UserInformation
In User
I have the following columns: Id(PK), userName and role.
In Password
I have: User_Id(PK and FK to User - Id column), password and oldPassword (if necessary).
In UserInformation
I have: User_Id(PK and FK to User - Id column), firstName, lastName and email.
As for inserting data, I have a separate class with string constants inside which are queries and I'm executing them by doing
sqlConnection.QueryAsync(QueryFromStringConstants, etcParams).
As I'm a little bit noobish with the SQL syntax and everything related to SQL in general(haha), my question is: if I create a User
, how can I insert data into all 3 tables at the same time?
Thanks:)
Each insert requires a separate insert statement, and you should also get an identity value after each insert in order to use it for next insert, for example:
INSERT INTO User (userName, role) VALUES (...)
DECLARE @userId AS integer = (SELECT @@IDENTITY);
But you can also use Entity framework. You should create class User
, which have virtual properties of type Password
and UserInformation
(also classes you should create as well). Then create a context which has a property DbSet<User> Users
. In this case you just create a User instance, populate its fields, Password and UserInformation with correspondent instances of Password and UserInformation classes. Then use:
context.Users.Add(userInstanceVar);
context.SaveChanges();
That's all, EF will save all instances into your database. and also populates all identity values automatically.
If your Primary Key on your User
table is an int
or bigint
, you use the function SCOPE_IDENTITY
to get the PK.
set nocount, xact_abort on; --recommended
begin transaction;
insert into user(User_Id,userName,...)
values(...);
declare @user_id int = scope_identity(); -- make sure this is the very next line after insert
insert into Password(User_Id,....)
values(@user_id,...);
insert into UserInformation(User_Id,....)
values(@user_id,...);
commit transaction;
If you are doing a multi-row insert, you can use Table-Valued Parameters. And then you will need the OUTPUT
clause to output the IDs into a new table variable:
set nocount, xact_abort on; --recommended
begin transaction;
declare @new_users table (user_id int, username varchar(50));
insert into user(User_Id,userName,...)
output inserted.user_id, inserted.username
select ...
from @users;
insert into Password(User_Id,....)
select u.user_id, ...
from passwords p
join @new_users u on u.username = p.username;
commit transaction;
I must say though, that I don't see the point in having a separate table for UserInformation
, after all, you cannot have a User
without UserInformation
, so you shouold combine these into one.
You have to insert in the primary table then into the others. and use transaction to run the three statements. the following is an example using oracle procedure:
create or replace PROCEDURE InsertUser(.. params ...)
as
temp_id number;
BEGIN
insert into user(User_Id,userName,...) values(...) returning User_Id into temp_id;
insert into Password(User_Id,....) values(temp_id,...);
insert into UserInformation(User_Id,....) values(temp_id,...);
commit;
exception when others then rollback;
END InsertUser;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.