简体   繁体   中英

How to insert data into multiple related tables in .NET Core API?

I want to insert data into multiple related tables, I searched, but everything I've found is insert data into multiple tables that aren't related. I have two tables User and OrchardTable, both are related by the user Id, so the primary key of the User table is the Id, which is generated as an identity on the database, and the foreign key of the table OrchardTable is the User Id.

This is from my controller

[HttpPost]
public ActionResult post([FromBody] Models.Users u)
{
    using (Models.OrchardAdminContext db = new Models.OrchardAdminContext())
    {
        Models.User oUser = new Models.User();

        Models.OrchardTable userOrchar = new Models.OrchardTable();

        oUser.Name = u.Name;
        oUser.Email = u.Email;
        db.User.Add(oUser);
        db.SaveChanges();
        
        var idUser = db.OrchardTable.Where(x => x.email = oUser.Email).FirstOrDefault();
        userOrchar.IdUser = idUser.Id;
        userOrchar.orchardUbication = u.ubication;
        db.OrchardTable.Add(userOrchard);
        db.SaveChanges();
    }
    return Ok();
}

So, the code above do: first adds an user to the User table, on the SQL Server Management Studio the Id of each user is an identity therefore when the data is saved the Id is generated and through the mail the id of the user is recovered to make the relation between the tables User and OrchardTable by the Id.

I think this is a way of do it, but not the best. Besides the main question, I want to know if there are a better and correct way to do the insert.

Any help is appreciated.

UPDATE Stored procedure to insert into the table User and return the Id from the same instert:

GO
SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE spUserInsert 
   @name varchar(20),
   @email varchar(100)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

-- Insert statements for procedure here
   insert into user(name, email) values (@name, @email);
   DECLARE @Id INT  
   SET @Id=@@IDENTITY  
   SELECT @Id AS id
END
GO

So if I'm not mistaken, the idea is to create an SP to insert and return the id of that insert, then with the id send it to another SP where it is inserted into OrchardTable. But now when I call it from the controller it doesn't seem to work because no saved record shows up in the database.

The controller:

    [HttpPost]
    public ActionResult post([FromBody] Models.Users u)
    {
        using (Models.OrchardAdminContext db = new Models.OrchardAdminContext())
        {
            Models.User oUser = new Models.User();

            Models.OrchardTable userOrchar = new Models.OrchardTable();

            oUsuar.Name = u.Name;
            oUsuar.Email = u.Email;
            
            var idUserReg = db.User.FromSqlRaw("Execute spUserInsert @name, @email", oUsuar.Name, oUsuar.Email);

            db.SaveChanges();

        }
        return Ok();
    }

I tested the stored procedure on Sql Server and works, but on the controller not, and I don't know why on the controller din't work. Again, any help is appreciated.

Try this:

var pName = new SqlParameter("@name", oUsuar.Name);
var pEmail = new SqlParameter("@email", oUsuar.Email);
            
var idUserReg = db.DataBase.ExecuteSqlCommand("Exec spUserInsert @name, @email", 
new[] { pName, pEmail });

With respect to the procedure to encapsulate the insert, this is what I had in mind you could do

create procedure UserInsert 
@Name varchar(20),
@Email varchar(100)
<@anyOtherParameters>
as
set nocount, xact_abort on

declare @Id int

begin tran
    insert into [user]([name], email)
    values (@Name, @Email);

    set @Id=Scope_Identity();

    insert into OrchardTable (Id, <othercolumns?>)
    values (@Id, @OtherParams?);
commit tran
go

You only need to make one call from code, the procedure will insert the user , get the identity and then insert this Id into the OrchardTable

If you need to include any other data just pass as paramters also and use for the insert - if you only want a row with the corresponding ID then just leave as a single insert for the Id.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM