使用Dapper

时间:2016-06-14 08:20:51

标签: c# dapper

dapper无论如何都可以将数据库中的两列映射到一个.Net数据类型? 我的情况是我在数据库中有货币值表示为两列。

Cost         Decimal(19,4)  
CostCurrency char(3)

我希望它映射到自定义数据类型Money

public partial struct Money
{
   public Money(decimal amount, string currency)
   {
   }
}

例如在保险实体上:

public class Insurance
{
    public string Id {get;set;}
    public Money Cost {get;set;}
}

我一直在关注SqlMapper.TypeHandler<Money>,但它似乎一次只能读/写一列。

3 个答案:

答案 0 :(得分:2)

我倾向于发现,通过使用私有属性来表示数据存储,可以大大简化复杂属性的任何映射。 Dapper将映射到私有财产。

public class Insurance
{
    #region Data
    private decimal Cost{get{return this.CurrentCost.Amount;} set{this.CurrentCost.Amount = value;}}
    private string Currency{get{return this.CurrentCost.Currency;} set{this.CurrentCost.Currency = value;}}
    #endregion


    public string Id {get;set;}

    //Changed prop name to not confuse it with storage columns
    public Money CurrentCost {get;set;}

    public Insurance(){
        //initialize this so that it won't blow up on mapping
        this.CurrentCost = new Money();
    }
}

乍一看,感觉就像我们正在标记我们的物体相当多,以使其坚持并映射。但它如此直截了当,没有神奇的映射,它只是起作用。您也可以对所有这些进行单元测试。即使是一个拥有数百个持久对象的项目,这项技术只会占用一小部分时间,并且在整个项目的发展过程中完全灵活和易于管理。

答案 1 :(得分:1)

原来我需要使用dapper的Split功能:

var insurance = (await con.QueryAsync<Insurance, decimal, string, Insurance>(
                   sql,
                   (entity, cost, costCurrency) =>
                   {
                       entity.Cost = new Money(cost, costCurrency);
                       return entity;
                   },
                   splitOn: "Cost, CostCurrency",
                   param: new { Id = id })).Single();

答案 2 :(得分:0)

它不漂亮,但这是另一种选择:

var result = conn.Query(@"select Id = '1', Amount = 12.99, Currency = 'USD' 
                    union all select Id = '2', Amount = 29.58, Currency = 'CAD'")
.Select(row => new Insurance() { Id = row.Id, Cost = new Money(row.Amount, row.Currency) })
.ToList();