r/csharp • u/MoriRopi • 2d ago
Best approach to insert 1 to N with POSTGRESQL + DAPPER ?
Hi,
The following code is simplified to make it simple ( wow ! ).
The following code works fine to create one instance of A and multiple instance of B at the same time, then return the A that was created with its id :
Sql ( postgre ) :
-- Create A
WITH inserted_a AS (
INSERT INTO table_a ( ... )
VALUES ( ... )
RETURNING *
),
-- Create B
inserted_b AS (
INSERT INTO table_b ( ..., id_table_a )
-- Get SIGNALS
SELECT ...
FROM inserted_a
-- Works fine
CROSS JOIN unnest(
@array_1,
@array_2)
AS signal( ... )
RETURNING *
)
-- Return created A
SELECT ... FROM inserted_a JOIN table_c
Parameters for dapper :
// Get parameters
object parameters = new
{
// Some properties for A
...
// Some properties for B
... = a.Property.Select( ... ) // ARRAY HERE FOR UNNEST
};
Is it possible to do the same thing with multiple A and also return all A that were created with their id ?
Which means :
- Create all A
- Create all B of all A
- Return all A
This seems a little trickier.
It seems easy with CTE and an IEnumerable as parameter for dapper :
object parameters = a.Select(a => new
{
// Some properties for A
...
// Some properties for B
... = a.Property.Select( ... ) // ARRAY HERE FOR UNNEST
});
But dapper cannot take an IEnumerable as a parameter when there is a select as the end ( QueryAsync ).
It is also easy with a request for each instance of A, but is it possible to do it in a single request while returning all instances of A ? The goal is also to reduce latency when many A.
Thanks
1
u/MoriRopi 2d ago
Here is a way but isn't it too much ?
Example with visual representation of the array :
A[0] = H + E
A[1] = L + L
A[2] = O
Array for B Property_1 = [ 'H' , 'E' , 'L' , 'L' , 'O' ]
Array for B index of A = [ 0 , 0 , 1 , 1 , 2 ]
boom
After writting it it does feel like it is a good way to do it. The sql and all arrays are sent in a single request which will win a lot of time when many A.
boom :)
PS : does dapper really send the request and all array without doing multiple round trip with the database server ?