2017-09-06 21 views
3

2つの関連するテーブルにレコードのバッチを挿入しようとしていますDapperを使ってPostgreSQLの2つの関連するテーブルに(配列を)バッチ挿入する方法は?

たとえば、テーブルがparent sおよびそのchildrenのバッチを挿入するには

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) 
); 

あり、私は次のようにします - 以下のクラスは、私はDapperの

を使用してい便宜上上記の表

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;} 
} 

にマッピングされています

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が2回目のバッチインサートで使用できないため、明らかにこれは機能しません。あなたは、最初の挿入から挿入されたparent_idを取得し、2番目のものと一緒に使用する方法はありますか?あるいは、バッチインサート関連のデータと同じ結果を得るための別の方法がありますか?

注1:挿入された値がパラメータ化配列https://dba.stackexchange.com/questions/89451/inserting-into-related-tables

注2でない場合、これは、データ修正CTEで簡単に行うことができる。別のアプローチ私が考えることができるが事前移入されselect nextval('parent_id_seq') from generate_series(1, <number of parents inserting which we know beforehand>)のようなものでシーケンス値をあらかじめ割り当てておくことで(挿入前の)コード内の主キーを削除できますが、これは私の正しいアプローチのようには見えません。

答えて

1

2番目の注釈 - 「事前割り当て」のシーケンス値は、これを行うのに非常に正当な方法であり、時にはhi-loとも呼ばれます。 Entity Frameworkコアプロバイダは、この動作を標準機能としてサポートしています。

関連する問題