学海无涯

导航

Dapper 在继承层次结构中处理数据

Dapper 包含一项功能,用于处理可能逐行映射到不同类型的数据。在处理使用Table Per Hierarchy存储模式的继承层次结构时,此功能特别有用,即一个表用于表示层次结构中的所有类。“鉴别器”列用于区分类型。

以下类定义表示基于抽象Contract类型的继承层次结构。还定义了三种派生类型,代表通信/媒体业务提供的不同类型的合同。ContractType属性充当鉴别器。

public abstract class Contract
{
    public int ContractId { get; set; }
    public DateTime StartDate { get; set; }
    public int DurationMonths { get; set;}
    public decimal Charge { get; set; }
    public ContractType ContractType { get; set; }
    public int CustomerId { get; set; }
}

public class MobileContract : Contract
{
    public MobileContract() => ContractType = ContractType.Mobile;
    public string MobileNumber { get; set; }
}

public class TvContract : Contract
{
    public TvContract() => ContractType = ContractType.TV;
    public TVPackageType TVPackageType { get; set; }
}

public class BroadBandContract : Contract
{
    public BroadBandContract() => ContractType = ContractType.Broadband;
    public int DownloadSpeed { get; set; }
}

public enum TVPackageType
{
    S, M, L, XL
}

public enum ContractType
{
    Mobile = 1, TV, Broadband 
}

  这些类映射到具有以下架构(SQLite)的单个表:

 

 以下代码显示了如何使用ExecuteReaderGetRowsParser<T>方法根据当前正在读取的合约类型填充三个集合:

var tvContracts = new List<TvContract>();
var mobileContracts = new List<MobileContract>();
var broadbandContracts = new List<BroadbandContract>();

var sql = @"select * from contracts";
using (var connection = new SQLiteConnection(connString))
using (var reader = connection.ExecuteReader(sql))
{
    var tvContractParser = reader.GetRowParser<TvContract>();
    var mobileContractParser = reader.GetRowParser<MobileContract>();
    var broadbandContractParser = reader.GetRowParser<BroadbandContract>();
    
    while(reader.Read())
    {
        var discriminator = (ContractType)reader.GetInt32(reader.GetOrdinal(nameof(ContractType)));
        switch(discriminator)
        {
            case ContractType.TV:
                tvContracts.Add(tvContractParser(reader));
                break;
            case ContractType.Broadband:
                broadbandContracts.Add(broadbandContractParser(reader));
                break;
            case ContractType.Mobile:
                mobileContracts.Add(mobileContractParser(reader));
                break;
        }
    }
}
Console.WriteLine("TV Contracts");
tvContracts.ForEach(c => Console.WriteLine($"Duration: {c.DurationMonths} months, Package Type: {c.TVPackageType.ToString()}"));
Console.WriteLine("Broadband Contracts");
broadbandContracts.ForEach(c => Console.WriteLine($"Duration: {c.DurationMonths} months, Cost: {c.Charge}, Download: {c.DownloadSpeed} Mbps"));
Console.WriteLine("Mobile Contracts");
mobileContracts.ForEach(c => Console.WriteLine($"Duration: {c.DurationMonths} months, Number: {c.MobileNumber}"));

  

 

posted on 2022-10-04 17:33  宁静致远.  阅读(49)  评论(0编辑  收藏  举报