Dapper自定义类型数组

时间:2017-08-03 11:16:50

标签: c# postgresql dapper

使用dapper我正在尝试映射一个自定义类型数组的列,但似乎没有任何示例。这是表格定义:

CREATE TABLE public."Data"
(
    "Id" bigint NOT NULL DEFAULT nextval('"Data_Id_seq"'::regclass),
    "Value" real NOT NULL,
    "UDFs" "UDF"[],
    "Timestamp" timestamp with time zone NOT NULL,
    CONSTRAINT "Data_pkey" PRIMARY KEY ("Id")
)

请注意此处的UDF列,其定义如下:

CREATE TYPE public."UDF" AS
(
    "Name" text,
    "Value" text
);

现在我的模型设置如下:

public class Data
{
    [Key]
    public long Id { get; set; }

    [Required]
    public float Value { get; set; }

    [Required]
    public DateTime Timestamp { get; set; }

    [Required]
    public UDF[] UDFs { get; set; }

}

和UDF类:

public class UDF 
{
    public string Name {get;set;}
    public string Value {get;set;}
}

但我得到以下例外:

Exception has occurred: CLR/System.InvalidOperationException
An exception of type 'System.InvalidOperationException' occurred in Dapper.dll but was not handled in user code: 'Error parsing column 2 (UDFs=2 - Single)'
   at Dapper.SqlMapper.ThrowDataException(Exception ex, Int32 index, IDataReader reader, Object value)
   at Dapper.SqlMapper.<QueryImpl>d__124`1.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Dapper.SqlMapper.Query[T](IDbConnection cnn, String sql, Object param, IDbTransaction transaction, Boolean buffered, Nullable`1 commandTimeout, Nullable`1 commandType)
   at backend.Repository.DataRepository.FindAll() in c:\Users\davidk\Desktop\ProjectSaturn\backend\Repository\DataRepository.cs:line 43
   at backend.Controllers.ValuesController.Get() in c:\Users\davidk\Desktop\ProjectSaturn\backend\Controllers\ValuesController.cs:line 26
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionMethodAsync>d__27.MoveNext()

我已经读过你需要使用自定义类型映射器,但我真的看不到任何好的例子。有谁知道我会在哪里找到更多信息?

哦我正在使用的数据库是postgres。

1 个答案:

答案 0 :(得分:2)

您的UDF列包含数组?我不认为Dapper可以在一列中处理数组值。更典型的情况是为UDF创建一个单独的表,然后在查询中加入它们。

public class UDF
{
    [Key]
    public long Id { get; set; }

    [Required]
    public string Name { get; set; }

    [Required]
    public string Value { get; set; }
}

public class Data
{
    [Key]
    public long Id { get; set; }

    [Required]
    public float Value { get; set; }

    [Required]
    public DateTime Timestamp { get; set; }

    [Required]
    public List<UDF> UDFs { get; set; }
}

string sql = @"SELECT
        d.Id,
        d.Value,
        d.Timestamp,
        u.name,
        u.value
FROM Data d
INNER JOIN UDFTable u ON d.Id = u.Id";

然后你可以做

QueryAsync<Data, UDF, Data>(
        sql,
        (data, udf, data) => {
            data.UDFs.Add(udf);
            return data;
        },
        new { },
        null, true, "Id", null, System.Data.CommandType.Text)