微信号:cnmsdn

介绍:微软中国MSDN开发社区官方微信.

Dapper 自定义栏位对应的三种方式

2016-08-25 07:17 软件主厨

看到一段某公司对外服务的系统的代码,这段代码写好不到一年,而这段代码在做一件事情,把从资料库捞到的资料转成物件集合,做法就是用 ADO.NET 产生 SqlDataReader,再将 SqlDataReader 丢到一个静态方法,在静态方法里面逐笔读取资料,接着透过 Reflection 动态地产生物件集合,但是物件的 Property Name 就迁就 ColumnName,一整个怪啊!


如果我们要练习Reflection 的用法,这是个非常好的练习,但是要用在 Production 上我们还有 Dapper 可以选择,搭配我接下来要介绍的三种自定义栏位对应方式,我相信怎样都比自己写 Reflection 来得好。


首先我有这样一个资料表,我拿这个资料表来当范例。

然后,我要把上头的资料表对应成下面这个类别。

Dapper.FluentColumnMapping

Dapper.Fluent ColumnMapping 是我要介绍的第一种,这个用起来就非常简单,提供的功能也很单纯,就是做栏位的对应而已,话不多说,来看一下范例代码。

[TestMethod]public void Test_FluentColumnMapping(){    var columnMappings = new ColumnMappingCollection();

    columnMappings.RegisterType<Product>()
                  .MapProperty(x => x.Id).ToColumn("MyId")
                  .MapProperty(x => x.Name).ToColumn("MyName")
                  .MapProperty(x => x.Price).ToColumn("Num_Price");

    columnMappings.RegisterWithDapper();

    IEnumerable<Product> products;    using (SqlConnection sql = new SqlConnection(connectionString))
    {
        products = sql.Query<Product>(@"SELECT * FROM TestTable");
    }

    Assert.AreEqual("無線網路分享器", products.Single().Name);
}

使用上,资料型态一定要注意一下,至少逻辑上要可以转型转得过去

举个例子,资料库内的资料型态是 nvarchar(50),资料内容是 2016/01/01 00:00: 00,那么 Property 的资料型别可以是 DateTime,工具会自动帮你转型,但不要来个资料内容是我死硬要转,硬要转成 DateTime,那就是来乱的。

Dapper.FluentMap

第二个要介绍的是 Dapper.Fluent Map,这个工具要多做一件事情,要先产生一个继承自 EntityMap<T> 类别,用来定义栏位对应的规则。

public class ProductMap : EntityMap<Product>
{    public ProductMap()    {
        Map(x => x.Id).ToColumn("myid", false);
        Map(x => x.Name).ToColumn("MyName");
        Map(x => x.Price).ToColumn("Num_Price");
    }
}

ToColumn() 方法中把 caseSensitive 参数设为 false 就可以不管栏位名称的大小写,接着初始化之后就可以了,我们看下面使用范例。

[TestMethod]public void Test_FluentMap(){
    FluentMapper.Initialize(cfg =>
    {
        cfg.AddMap(new ProductMap());
    });

    IEnumerable<Product> products;    using (SqlConnection sql = new SqlConnection(connectionString))
    {
        products = sql.Query<Product>(@"SELECT * FROM TestTable");
    }

    Assert.AreEqual("無線網路分享器", products.Single().Name);
}

这个工具也会像前面一个工具一样自动帮忙转型,虽然操作上较为繁琐,但是它可以提供像是Convetion Mapping、Transformation 的功能,搭配Dommel 套件还可以做简单的CRUD。

實作 SqlMapper.ITypeMap

如果你觉得使用别人做好的工具,是看轻您的程式撰写功力,Dapper 里面有一个介面 SqlMapper.ITypeMap,您可以实作它,国外也有神人帮您弄好了 kalebpederson/ColumnAttributeTypeMapper.cs,使用这种方式需要搭配 ColumnAttribute,怎么搭配请看下面。

public class Product{
    [Column("MyId")]    public int Id { get; set; }

    [Column("MyName")]    public DateTime Name { get; set; }

    [Column("Num_Price")]    public int Price { get; set; }    public string Memo { get; set; }
}

接着呼叫 SqlMapper.SetTypeMap 把要对应的类别跟栏位映射丢进去就可以了。

[TestMethod]public void TestMethod1(){
    Dapper.SqlMapper.SetTypeMap(        typeof(Product),        new ColumnAttributeTypeMapper<Product>());

    IEnumerable<Product> products;    using (SqlConnection sql = new SqlConnection(connectionString))
    {
        products = sql.Query<Product>(@"SELECT * FROM TestTable");
    }

    Assert.AreEqual("無線網路分享器", products.Single().Name);
}

这种做法一样会自动帮忙转型,以上就Dapper 可以支援的三种自定义栏位的方式做个介绍,善用工具可以事半功倍,这个「功」倍不只是撰写 Production Code 当下的功,也有后续维护的功。

 
微软中国MSDN 更多文章 如何修改 Visual Studio Code 内建的 TypeScript 版本 【直播预告】北美微软 Ignite 技术大会 Linux 版的 PowerShell 发布啰!而且是开源的喔! {x:Bind} 标记扩展 可视化层
猜您喜欢 QQ群升级 联合太平洋公司首席信息官:大数据提升铁路运输安全 MVC4 WebAPI(一) 做网站,如何赚到人生的第一个100万? Apache\/Nginx通过UserAgent屏蔽蜘蛛和采集