如何使用Dapper FluentMap将postgresql UUID解析为C#字符串?

时间:2018-03-30 18:13:24

标签: c# postgresql dapper npgsql dapper-fluentmap

我有一个返回(除其他外)UUID的函数。我正在使用FluentMap来处理一些包含空格的返回列,但是有问题的列(invoice_id)没有这个问题。

db查询的缩写版本:

CREATE FUNCTION fnSearchInvoices (
    _SearchTerm TEXT
) 
RETURNS TABLE(
    store_id INTEGER,
    customer_id TEXT,
    "Customer Name" TEXT,
    "Store Name" TEXT,
    "Email" TEXT,
    invoice_id UUID
) AS $$
SELECT
I.store_id,
I.customer_id,
C.name AS "Customer Name",
S.name AS "Store Name",
C.email AS "Email",
I.id AS invoice_id
FROM Invoice I
JOIN Customer C
ON I.customer_id = C.id
JOIN Store S
ON I.store_id = S.id
WHERE
{bunch of conditions for matching search term}
;
$$ LANGUAGE SQL;

请求类:

public class SearchRequest
{
    public string SearchTerm { get; set; }
    public int PagingOffSet { get; set; }
    public int PageSize { get; set; }
    public string SortField { get; set; }
    public string SortDirection { get; set; }
}

结果类:

public class SearchResult
{
    public int StoreID { get; set; }
    public string CustomerID { get; set; }
    public string CustomerName { get; set; }
    public string StoreName { get; set; }
    public string Email { get; set; }
    public string InvoiceID { get; set; }
    public int TotalRecords { get; set; }
}

EntityMap:

public class SearchResultMap : EntityMap<SearchResult>
{
    public SearchResultMap()
    {
        Map(p => p.CustomerID).ToColumn("Customer Name");
        Map(p => p.StoreName).ToColumn("Store Name");
    }
}

最后,从C#调用数据库:

IDbConnection dbConnection = new NpgsqlConnection(strDbConnectionString)

string strCommand = "SELECT *, count(*) OVER() AS total_records ";
strCommand += "FROM fnSearchInvoices(:SearchTerm) ";
strCommand += "ORDER BY \"" + cSearchRequest.SortField + "\" " + cSearchRequest.SortDirection + " ";
strCommand += "LIMIT :PageSize OFFSET :PagingOffSet;";

cSearchResponseList = dbConnection.Query<T>(strCommand, cSearchRequest).ToList();

当我使用异常处理运行上面的代码时,我收到以下错误(这是一条异常消息加上内部消息):

Error: Error parsing column 6 (invoice_id=12345678-abcd-1234-abcd-1234567890ef - Object) Details: System.InvalidCastException: Object must implement IConvertible. at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider) at Deserializeabcdef12-abcd-1234-abcd-abcdef123456(IDataReader )

我可以从InvoiceID类中删除SearchResponse,查询工作正常;它会忽略该列,其他所有内容都按预期映射。

db函数正在其他地方使用,我宁愿不改变它,尽管作为最后的手段,我可​​以在函数中进行转换。它只需要在其他地方进行额外的更改,这些更改超出了我正在处理的范围。我意识到我应该能够更改我的C#中的SELECT,通过按名称而不是*来获取所有列,在函数调用之外显式地将UUID转换为TEXT,我将在下一步尝试。但是为了将来参考,有没有办法让Dapper将查询中的UUID返回正确映射到C#字符串?

1 个答案:

答案 0 :(得分:1)

可悲的是,Dapper将尝试通过数据库专门为类型提供的内容来关联该类型。您的发票列被指定为字符串类型。

如果您有查询返回列:

abstract

Dapper现在可以正确映射到您指定为字符串的对象。这应该纠正你的问题。最安全的最好方法是让数据库正确地将您的列转换为CAST([Invoice] AS NVARCHAR(MAX)) AS [Invoice]

否则您需要更改对象属性。

NVARCHAR(MAX)