phnx47 / dapper-repositories

CRUD for Dapper

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Insert with PK specified ignores explicit PK value suppplied

b2soft opened this issue · comments

Hello. I have 2 tables representing 1-1 relationship:

  • user_auth_data containing user_id as PK auto incerement value
  • user_special_data which also has user_auth_data as PK + FK constraint to user_auth_data.user_id

Classes are mapped like this:

[Table("user_auth_data")]
public class UserAuthDataModel
{
	[Key, Identity]
	public int UserId { get; set; }
	public string Foo { get;set; }
}

[Table("user_special_data")]
public class UserSpecialDataModel
{
	[Key, Identity]
	public int UserId { get; set; }
	public string Bar { get; set; }
        public string Baz { get; set; }
}

I insert a record to user_auth_data to get generated user_id, and now I have to add a row to user_special_data and it inserts null user_id.

var id = .. // get id from user_auth_data;
var newData = new UserSpecialDataModel{ UserId = id };
await repository.InsertAsync(newData);

I quickly logged the queries generated (Postgresql), and it seems like sql generated is not correct:
2023-08-12 02:45:15.716 CEST [14780] LOG: execute <unnamed>: INSERT INTO user_special_data (bar, baz) VALUES ($1, $2) RETURNING user_id
so it seems like user_id is ignored completely.

To note, direct query
await repository.Connection.ExecuteAsync($"INSERT INTO user_special_data (user_id) VALUES ({id})");
works as expected.

Is it a bug or intended behavior?

@b2soft Intended behavior.

Look at tests:

public static void InsertQuoMarks()
{
ISqlGenerator<Address> userSqlGenerator = new SqlGenerator<Address>(_sqlConnector, true);
var sqlQuery = userSqlGenerator.GetInsert(new Address());
Assert.Equal("INSERT INTO [Addresses] ([Street], [CityId]) VALUES (@Street, @CityId) SELECT SCOPE_IDENTITY() AS [Id]", sqlQuery.GetSql());
}

Thanks for the answer, so the only way to put the PK into - raw SQL query?

@b2soft If you don't want to use auto increment and put value yourself you should remove Identity attribute.

Look at:

var properties =
(IsIdentity
? SqlProperties.Where(p => !p.PropertyName.Equals(IdentitySqlProperty.PropertyName, StringComparison.OrdinalIgnoreCase))
: SqlProperties).ToList();