如何在 .NET Core API 中将数据插入到多个相关表中?
How to insert data into multiple related tables in .NET Core API?
我想将数据插入到多个相关的 table 中,我进行了搜索,但我发现的所有内容都是将数据插入到多个不相关的 table 中。我有两个tables User和OrchardTable,都是通过用户Id关联的,所以Usertable的主键就是Id,在数据库上作为身份生成,而外table OrchardTable 的键是用户 ID。
这是我的控制器
[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();
}
所以,上面的代码做的是:首先将一个用户添加到用户 table,在 SQL Server Management Studio 上,每个用户的 Id 是一个身份,因此当数据被保存时生成Id并通过邮件恢复用户的id,通过Id建立tables User和OrchardTable之间的关系。
我认为这是一种方法,但不是最好的。除了主要问题,我想知道是否有更好更正确的插入方式。
感谢任何帮助。
更新
存储过程插入 table 用户和 return 来自同一插入的 ID:
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
因此,如果我没记错的话,我的想法是创建一个 SP 来插入和 return 该插入的 ID,然后使用该 ID 将其发送到另一个 SP,然后将其插入到 OrchardTable 中。但是现在当我从控制器调用它时它似乎不起作用,因为数据库中没有显示保存的记录。
控制器:
[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();
}
我在 Sql 服务器上测试了存储过程并工作,但在控制器上没有,我不知道为什么在控制器上不能工作。
再次感谢您的帮助。
试试这个:
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 });
关于封装插入的过程,这是我想你可以做的
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
您只需要从代码调用一次,该过程将插入 user
,获取 identity
,然后将此 Id 插入 OrchardTable
如果您需要包含任何其他数据,也只需作为参数传递并用于插入 - 如果您只需要具有相应 ID 的行,则只需将其作为 Id 的单个插入即可。
我想将数据插入到多个相关的 table 中,我进行了搜索,但我发现的所有内容都是将数据插入到多个不相关的 table 中。我有两个tables User和OrchardTable,都是通过用户Id关联的,所以Usertable的主键就是Id,在数据库上作为身份生成,而外table OrchardTable 的键是用户 ID。
这是我的控制器
[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();
}
所以,上面的代码做的是:首先将一个用户添加到用户 table,在 SQL Server Management Studio 上,每个用户的 Id 是一个身份,因此当数据被保存时生成Id并通过邮件恢复用户的id,通过Id建立tables User和OrchardTable之间的关系。
我认为这是一种方法,但不是最好的。除了主要问题,我想知道是否有更好更正确的插入方式。
感谢任何帮助。
更新 存储过程插入 table 用户和 return 来自同一插入的 ID:
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
因此,如果我没记错的话,我的想法是创建一个 SP 来插入和 return 该插入的 ID,然后使用该 ID 将其发送到另一个 SP,然后将其插入到 OrchardTable 中。但是现在当我从控制器调用它时它似乎不起作用,因为数据库中没有显示保存的记录。
控制器:
[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();
}
我在 Sql 服务器上测试了存储过程并工作,但在控制器上没有,我不知道为什么在控制器上不能工作。 再次感谢您的帮助。
试试这个:
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 });
关于封装插入的过程,这是我想你可以做的
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
您只需要从代码调用一次,该过程将插入 user
,获取 identity
,然后将此 Id 插入 OrchardTable
如果您需要包含任何其他数据,也只需作为参数传递并用于插入 - 如果您只需要具有相应 ID 的行,则只需将其作为 Id 的单个插入即可。