簡體   English   中英

參數對象的Dapper自定義映射

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM