Dapper array de tipos personalizados

c# dapper postgresql

Pregunta

Usando dapper intento mapear una columna que es una matriz de tipos personalizados pero parece que no hay ningún ejemplo de esto en ninguna parte. Aquí está la definición de la tabla:

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")
)

Tenga en cuenta la columna de UDF aquí que se define de la siguiente manera:

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

Ahora tengo mi modelo establecido como tal:

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; }

}

Y la clase UDF:

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

Pero obtengo la siguiente excepción:

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()

He leído que necesita utilizar un mapeador de tipos personalizado, pero realmente no puedo ver ningún buen ejemplo de esto. ¿Alguien sabe dónde encontraría más información?

Oh, el DB que estoy usando es postgres.

Respuesta popular

¿Su columna de UDF contiene una matriz? No creo que Dapper pueda tratar con valores de matriz en una sola columna. El caso más típico sería tener una tabla separada para UDF, luego unirlas en la consulta.

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";

entonces puedes hacer

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


Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué