如何将 Dapper 与派生类型一起使用

问题描述 投票:0回答:1

我有大约 20 个派生自

ModelBase
的类(其中包含常见的东西,如
CreationDate
Id
等)。

使用Dapper,可以很容易地保存和删除这些派生类(所有工作都是由倒数第二行完成的)

public static bool ModelDelete(ModelBase model, SqlConnection? conn = null, SqlTransaction? trans = null)
{
    bool connectionIsNew = (conn is null);
    bool transactionIsNew = (trans is null);

    try
    {
        if (connectionIsNew) 
            conn = new SqlConnection(Globals.connString);

        if (conn is null)
        {
            throw new Exception("Unable to establish a database connection in Data.ModelDelete");
            return false;
        }
        else
        {
             if (conn.State != System.Data.ConnectionState.Open) 
                 conn.Open();
        }

       if (transactionIsNew) 
           trans = conn.BeginTransaction();

        DynamicParameters p = new DynamicParameters();
        p.Add("Id", model.Id, DbType.Int32);
        p.Add("Error", null, DbType.String, ParameterDirection.Output, 8000);
        string spName = $"sp{model.GetType().Name}_Delete";
        int recordsAffected = conn.Execute(spName, p, trans);
    }
    catch (Exception exc)
    { }
}

但我似乎无法使用

Get
/
Fetch
命令做同样的事情并最终得到

public static ModelBase ModelGet(Type t, int id, SqlConnection? conn = null, SqlTransaction? trans = null, bool withDependents = false)
{
    bool connectionIsNew = (conn is null);
    bool transactionIsNew = (trans is null);
    ModelBase model = default!;

    try
    {
        if (connectionIsNew) 
           conn = new SqlConnection(Globals.connString);

        if (conn is null)
        {
             throw new Exception("Unable to establish a database connection in Data.ModelGet");
        }
        else
        {
            if (conn.State != System.Data.ConnectionState.Open) 
                conn.Open();

            if (transactionIsNew) 
                trans = conn.BeginTransaction();

            var p = new { Id = id };

            string spName = $"sp{t.Name}_Get";

            switch (t.Name)
            {
                case nameof(Account):
                    model = conn.QuerySingle<Account>(spName, p, trans);
                    break;

                case nameof(AccountGroup):
                    model = conn.QuerySingle<AccountGroup>(spName, p, trans);
                    break;

                case nameof(Address):
                    model = conn.QuerySingle<Address>(spName, p, trans);
                    break;

                case nameof(Agency):
                    model = conn.QuerySingle<Agency>(spName, p, trans);
                    break;

等等所有不同的派生模型类。这可行但不优雅。有没有比为每个派生类使用单独的

conn.QuerySingle<>
更好的方法?

c# dapper derived-types
1个回答
0
投票

因为您依赖于

Type
,所以您可以将其转换为类似这样的通用方法:

public static T ModelGet<T>(int id, SqlConnection? conn = null, SqlTransaction? trans = null, bool withDependents = false)
where T : ModelBase, class
{
    try
    {
        if (conn is null) 
           conn = new SqlConnection(Globals.connString);

        if (conn.State != System.Data.ConnectionState.Open) 
            conn.Open();
        
        if (trans is null) 
            trans = conn.BeginTransaction();

        return conn.QuerySingle<T>($"sp{typeof(T).Name}_Get", new { Id = id }, trans);
    
    }
    catch(Exception)
    {
        
    }
    
    return null;
}

您也可以对删除方法执行相同的操作。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.