[英]Dapper Custom Mapping For Param Object
我在PostgreSQL中有下表:
CREATE TABLE "user" (
id UUID NOT NULL,
name VARCHAR (50) NULL,
email VARCHAR (50) NOT NULL,
CONSTRAINT pk_user PRIMARY KEY (id)
);
此數據庫中的所有函數在參數名稱上均使用下划線( _
)前綴。 例:
CREATE OR REPLACE FUNCTION user_read_by_id
(
_id uuid
)
RETURNS SETOF "user"
LANGUAGE 'plpgsql'
AS
$BODY$
BEGIN
RETURN QUERY
SELECT
*
FROM
"user"
WHERE
"id" = _id;
END
$BODY$;
和
CREATE OR REPLACE FUNCTION user_create
(
_id uuid,
_name varchar(50),
_email varchar(50)
)
RETURNS VOID
LANGUAGE 'plpgsql'
AS
$$
BEGIN
INSERT INTO "user"
(
id,
name,
email
)
VALUES
(
_id,
_name,
_email
);
END
$$
在使用Dapper的C#代碼中,我需要能夠使用此下划線前綴來映射User
對象參數,但允許它也映射回沒有下划線前綴的結果集。
public class User
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
DefaultTypeMap.MatchNamesWithUnderscores = true;
// This works because I am manually setting the `_id` parameter.
// Ideally, it would match the User object and just use `Id`.
using(var connection = new NpgsqlConnection(ConnectionString))
{
var results = await connection.QueryAsync<User>(
"user_read_by_id",
new { _id = new Guid("38745b2e-436c-4593-827e-6ae123f12db5") },
commandType: CommandType.StoredProcedure);
var user = results.SingleOrDefault();
}
// This breaks because the User object doesn't map correctly
// to the parameters of the PgSQL function.
using(var connection = new NpgsqlConnection(ConnectionString))
{
var results = await connection.ExecuteAsync(
"user_create",
new User
{
Id = new Guid("38745b2e-436c-4593-827e-6ae123f12db5"),
Name = "John",
Email = "j.smith@example.com"
},
commandType: CommandType.StoredProcedure);
}
我可以通過某種方式創建僅在param對象上自動添加下划線前綴的映射器嗎?
可能有更好的方法來解決此問題,但我創建了一種通過對param對象進行反射來處理此問題的方法,並創建了一個新的DynamicParameters
參數。
using(var connection = new NpgsqlConnection(ConnectionString))
{
var results = await connection.ExecuteAsync(
"user_create",
ToParam(new User
{
Id = new Guid("38745b2e-436c-4593-827e-6ae123f12db5"),
Name = "John",
Email = "j.smith@example.com"
}),
commandType: CommandType.StoredProcedure);
}
private DynamicParameters ToParam<T>(T obj)
{
var dp = new DynamicParameters();
var properties = typeof(T).GetProperties();
foreach(var property in properties)
{
dp.Add($"_{SnakeCase(property.Name)}", property.GetValue(obj));
}
return dp;
}
private string SnakeCase(string input)
{
if(string.IsNullOrWhiteSpace(input))
{
return input;
}
var startUnderscores = Regex.Match(input, @"^_+");
return startUnderscores + Regex.Replace(input, @"([a-z0-9])([A-Z])", "$1_$2").ToLowerInvariant();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.