2017-08-03 38 views
2

使用小巧我试图映射一个自定义类型的数组的列,但似乎没有任何地方的例子。下面是表的定义:自定义类型的小巧阵列

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

卜T I出现以下情况例外:

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

我已阅读,你需要使用自定义类型映射器,但我实在看不出这有什么好的例子。有谁知道我会在哪里找到更多信息?

哦,我使用的DB是postgres。

回答

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) 
+0

其实我看着这个方法,我不知道这就是我要找的。如果有多个UDF连接到单个Data行,则内部连接将返回多行。此外,您将UDF的Key设置为Data行的Key,这将不允许Data行和UDF表之间的一对多关系。唯一的方法是在UDF表上有一个外键列,但是我的问题是我想返回一行数据,即使它们是连接了多行UDF。 – Dave3of5

+0

对,UDF表将有一个外键给Data表。在我的例子中,u.ID将是数据键(不是UDF的PK)。 Dapper不会自动折叠依赖列表。所以,假设有一个数据和两个UDF。你最终得到的是两个Data对象的列表,除了每个对象都包含2个UDF之外,它们是相同的。所以当我向海报解释时,你最终不得不将它们折叠起来。 https://stackoverflow.com/questions/45463783/how-do-i-map-multiple-lists-with-dapper/45493011#45493011 –

+0

真棒谢谢我可能会尝试一下架构,但现在我只是将其转换为JSON。 – Dave3of5