我试图将一批记录插入两个相关的表
例如。表格是
CREATE TABLE public.parent
(
parent_id integer NOT NULL DEFAULT nextval('parent_id_seq'::regclass),
name integer,
CONSTRAINT parent_pkey PRIMARY KEY (parent_id)
);
CREATE TABLE public.child
(
child_id integer NOT NULL DEFAULT nextval('child_id_seq'::regclass),
parent_id integer,
name integer,
CONSTRAINT child_pkey PRIMARY KEY (child_id),
CONSTRAINT child_parent_id_fkey FOREIGN KEY (parent_id) REFERENCES public.parent (parent_id)
);
要插入一批parent
及其children
,我会执行以下操作 - 以下类映射到上表
public class parent
{
public int parent_id {get; set;}
public string name {get; set;}
public List<child> children {get; set;}
}
public class child
{
public int child_id {get; set;}
public string name {get; set;}
public int parent_id {get; set;}
}
为方便起见,我使用Dapper
var parents = new parent[] { ... }
var children = parents.SelectMany(p => p.children);
using (var connection = new NpgsqlConnection("..."))
{
// map class to tables
connection.MapComposite<parent>("public.parent");
connection.MapComposite<child>("public.child");
await connection.ExecuteAsync(@"
insert into parent (name)
select
p.name
from
unnest(@parents) p;
insert into child (parent_id, name)
select
c.parent_id,
c.name
from
unnest(@children) c;
",
new[] {
new NpgsqlParameter("parents", parents),
new NpgsqlParameter("children", children)
}, CommandType.Text);
}
显然,这不会起作用,因为parent_id
不适用于第二批插入。有没有办法从第一个插入中获取插入的parent_id
并将其与第二个插入一起使用,假设第二个使用参数化数组?或者是否有其他方法可以实现相同的结果,即批量插入相关数据?
注1:如果插入的值不是参数化数组https://dba.stackexchange.com/questions/89451/inserting-into-related-tables
,则可以使用数据修改CTE轻松完成此操作 注2:我能想到的另一种方法是预先填充代码中的主键(插入前),方法是使用select nextval('parent_id_seq') from generate_series(1, <number of parents inserting which we know beforehand>)
之类的方式预先分配序列值,但这样做对我来说,这看起来不是正确的做法。
答案 0 :(得分:1)
你的第二个音符 - “预先分配”序列值 - 这是一种非常合法的方式,有时也被称为hi-lo。实体框架核心提供程序将此行为作为标准功能支持。