I am using Dapper for the first time, I'm previously used to just writing my SQL directly.
I have a situation where I have a many-to-many relationship so that my classes look like this:
public class Product
{
public int Id {get;set;}
public string otherpropertiesremovedforbrevity Other {get;set;}
...
public List<Attachment> Attachment {get;set;}
}
public class Attachment
{
public int Id {get;set;}
public string Name {get;set;}
public string URL {get;set;}
}
In my DB I have a table to link them together which looks like this;
ProductId
AttachmentId
(A composite primary key and both with Fk to their repective tables).
But I don't know how to perform the insert. What I have is below
using (var connection = GetConnection)
{
connection.Open();
using (var transaction = connection.BeginTransaction())
{
string pINSERT = "INSERT INTO prodcat.Product (otherpropertiesremovedforbrevity) " +
" VALUES (@otherpropertiesremovedforbrevity) RETURNING Id;";
string sql = "insert into prodcat.AttachmentProductSpecificationLink (ProductSpecificationId, AttachmentId) values(@Id, @AttachmentId)";
var res = await connection.ExecuteScalarAsync(pINSERT, entity);
var arows = await connection.ExecuteAsync(aINSERT, entity.Attachment, transaction);
transaction.Commit();
return Convert.ToInt64(res);
}
}
But I get the error
column "attachmentid" does not exist.
So I'm obviously not going about this in the right manner. So what do I need to do in order to get this to work?
Postgresql is case sensitive and you have column names with capital letters, so I guess you should quote the column names in insert statement:
string sql = "insert into prodcat.AttachmentProductSpecificationLink (\"ProductSpecificationId\", \"AttachmentId\") values(@Id, @AttachmentId)";
For example if you run this script:
CREATE TABLE _test("colName" integer);
SELECT *
FROM _test
WHERE colName = 1;
You will get an error:
SQL Error [42703]: ERROR: column "colname" does not exist
Hint: Perhaps you meant to reference the column "_test.colName".
Position: 27
The correct way would be:
SELECT *
FROM _test
WHERE "colName" = 1;
I believe the code snippet below will work for you.
You should have 3 insert statements, for Product, Attachment and AttachmentProductSpecificationLink. In your sample code you are missing one. I made the assumption, that your aINSERT should be for the Attachment table.
Another thing I noticed, Your ExecuteScalarAsync was returning an object, so I used ExecuteScalarAsync<int> instead to cast correctly.
Your entity ( Product class) variable contains a List of Attachments, Normally I would perform an ExecuteAsync and pass in the List because it is plain Inserts with no returning Clause. But in your case you are returning the Ids so I opted to use a foreach loop to iterate over the attachments for the inserts.
Within the foreach loop I return the returning ID into the variable attachmentId and use it for the following insert into AttachmentProductSpecificationLink. Since we aren't return anything I perform an ExecuteAsync.
using (var connection = GetConnection())
{
connection.Open();
using (var transaction = connection.BeginTransaction())
{
string pINSERT = "INSERT INTO prodcat.Product (otherpropertiesremovedforbrevity) " +
" VALUES (@otherpropertiesremovedforbrevity) RETURNING Id;";
string aINSERT = "INSERT INTO prodcat.Attachment (Name, URL) " +
" VALUES (@Name, @Url) RETURNING Id;";
string sql = "insert into prodcat.AttachmentProductSpecificationLink (ProductSpecificationId, AttachmentId) values(@Id, @AttachmentId)";
var res = await connection.ExecuteScalarAsync<int>(pINSERT, entity, transaction);
foreach( var a in entity.Attachment)
{
var attachmentId = await connection.ExecuteScalarAsync<int>(aINSERT, a, transaction);
var arows = await connection.ExecuteAsync(sql, new { Id = res, AttachmentId = attachmentId }, transaction);
}
transaction.Commit();
return Convert.ToInt64(res);
}
}
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.