最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺析如何優(yōu)雅封裝.NET數(shù)據(jù)庫訪問層

 更新時(shí)間:2026年04月02日 15:09:56   作者:孟章豪  
這篇文章主要為大家詳細(xì)介紹了如何優(yōu)雅封裝.NET數(shù)據(jù)庫訪問層,解決SQL拼接和參數(shù)化查詢的痛點(diǎn),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下

但很多開發(fā)者在實(shí)際項(xiàng)目中仍然會遇到一個(gè)問題: 參數(shù)化寫法太繁瑣,代碼臃腫,開發(fā)效率低

那么有沒有一種方式可以做到:

  • 寫法簡潔(接近拼接SQL)
  • 自動參數(shù)化(安全)
  • 統(tǒng)一規(guī)范(易維護(hù))
  • 支持?jǐn)U展(日志、事務(wù)、重試)

答案是:封裝數(shù)據(jù)庫訪問層

一、為什么必須封裝

先說結(jié)論:

?? 不封裝數(shù)據(jù)庫訪問層,項(xiàng)目后期一定會亂

常見問題:

1. SQL散落各處

// A類
var sql = "SELECT * FROM A WHERE id=@id";

// B類
var sql = "SELECT * FROM A WHERE id=" + id;

寫法不統(tǒng)一,維護(hù)困難

2. 參數(shù)化風(fēng)格混亂

cmd.Parameters.AddWithValue("@id", id);

每個(gè)人寫法都不一樣

3. 無法統(tǒng)一擴(kuò)展

比如你想加:

  • SQL日志
  • 執(zhí)行耗時(shí)
  • 重試機(jī)制
  • 事務(wù)控制

需要全項(xiàng)目改代碼 

所以核心目標(biāo):把所有數(shù)據(jù)庫操作收口到一層

二、設(shè)計(jì)目標(biāo)(重點(diǎn))

我們要實(shí)現(xiàn)一個(gè)工具層,滿足:

目標(biāo)說明
簡潔類似拼接SQL寫法
安全自動參數(shù)化
通用支持查詢/增刪改
可擴(kuò)展日志/事務(wù)/重試
易維護(hù)統(tǒng)一入口

三、推薦方案:類Dapper風(fēng)格封裝

我們實(shí)現(xiàn)一個(gè)方法:

Execute(sql, new { id = 1, name = "張三" });

看起來像拼接,但其實(shí)是參數(shù)化

四、核心實(shí)現(xiàn)(通用工具類)

1. 執(zhí)行SQL(增刪改)

public static int Execute(string sql, object param = null)
{
    using (var conn = new SqlConnection(connStr))
    {
        using (var cmd = new SqlCommand(sql, conn))
        {
            if (param != null)
            {
                AddParameters(cmd, param);
            }

            conn.Open();
            return cmd.ExecuteNonQuery();
        }
    }
}

2. 查詢單條

public static T QueryFirst<T>(string sql, object param = null) where T : new()
{
    using (var conn = new SqlConnection(connStr))
    using (var cmd = new SqlCommand(sql, conn))
    {
        if (param != null)
        {
            AddParameters(cmd, param);
        }

        conn.Open();
        using (var reader = cmd.ExecuteReader())
        {
            if (!reader.Read()) return default;

            var obj = new T();
            foreach (var prop in typeof(T).GetProperties())
            {
                if (!reader.HasColumn(prop.Name)) continue;

                var val = reader[prop.Name];
                if (val != DBNull.Value)
                    prop.SetValue(obj, val);
            }

            return obj;
        }
    }
}

3. 參數(shù)自動映射(核心)

private static void AddParameters(SqlCommand cmd, object param)
{
    foreach (var prop in param.GetType().GetProperties())
    {
        var value = prop.GetValue(param) ?? DBNull.Value;
        cmd.Parameters.AddWithValue("@" + prop.Name, value);
    }
}

這一步就是關(guān)鍵:把匿名對象 → 自動轉(zhuǎn)成SQL參數(shù)

五、使用方式(對比)

舊寫法(拼接)

var sql = $"SELECT * FROM User WHERE Name='{name}'";

新寫法(推薦)

var sql = "SELECT * FROM User WHERE Name=@Name";
var user = QueryFirst<User>(sql, new { Name = name });

優(yōu)點(diǎn):

  • 簡潔
  • 安全
  • 可讀性強(qiáng)

六、進(jìn)階優(yōu)化(項(xiàng)目實(shí)戰(zhàn)重點(diǎn))

1. SQL日志(強(qiáng)烈建議)

Stopwatch sw = Stopwatch.StartNew();

var result = cmd.ExecuteNonQuery();

sw.Stop();
Console.WriteLine($"SQL執(zhí)行耗時(shí):{sw.ElapsedMilliseconds}ms");
Console.WriteLine(sql);

在MES/WMS中非常重要(排查慢SQL)

2. 異常重試機(jī)制

適用于:

  • 數(shù)據(jù)庫瞬時(shí)連接失敗
  • 網(wǎng)絡(luò)抖動
int retry = 3;
while (retry-- > 0)
{
    try
    {
        return cmd.ExecuteNonQuery();
    }
    catch
    {
        if (retry == 0) throw;
        Thread.Sleep(200);
    }
}

3. 事務(wù)封裝

public static void ExecuteInTransaction(Action<SqlConnection, SqlTransaction> action)
{
    using var conn = new SqlConnection(connStr);
    conn.Open();

    using var tran = conn.BeginTransaction();

    try
    {
        action(conn, tran);
        tran.Commit();
    }
    catch
    {
        tran.Rollback();
        throw;
    }
}

用法:

ExecuteInTransaction((conn, tran) =>
{
    Execute("INSERT ...", param1, conn, tran);
    Execute("UPDATE ...", param2, conn, tran);
});

4. 防止動態(tài)SQL注入(白名單)

var allowedColumns = new[] { "Name", "Age" };

if (!allowedColumns.Contains(column))
{
    throw new Exception("非法字段");
}

七、適配你當(dāng)前技術(shù)棧(重點(diǎn))

你現(xiàn)在用:

  • .NET
  • PostgreSQL / SQL Server
  • MES / WMS
  • 高并發(fā) + 設(shè)備數(shù)據(jù)

建議:

1. PostgreSQL(Npgsql)

把:

SqlCommand

換成:

NpgsqlCommand

2. 高頻接口建議

必須加:

  • SQL日志
  • 超時(shí)控制
  • 重試機(jī)制

3. 設(shè)備數(shù)據(jù)(你做過Socket)

強(qiáng)烈建議:

  • 所有入庫操作必須參數(shù)化
  • 禁止拼接

八、什么時(shí)候不用自己封裝

直接說實(shí)話:

如果項(xiàng)目不復(fù)雜,直接用:

  • Dapper(強(qiáng)烈推薦)
  • SqlSugar(你已經(jīng)在用)
  • FreeSQL

你自己封裝適合:

  • 公司沒有規(guī)范
  • 項(xiàng)目需要統(tǒng)一風(fēng)格
  • 想做技術(shù)沉淀

九、總結(jié)

數(shù)據(jù)庫訪問層的本質(zhì):不是為了封裝而封裝,而是為了統(tǒng)一和可控

到此這篇關(guān)于淺析如何優(yōu)雅封裝.NET數(shù)據(jù)庫訪問層的文章就介紹到這了,更多相關(guān).NET封裝數(shù)據(jù)庫訪問層內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

嘉善县| 南川市| 蓬安县| 无锡市| 永兴县| 南京市| 视频| 奉贤区| 军事| 高碑店市| 读书| 潮州市| 北安市| 洪泽县| 铁力市| 北宁市| 安达市| 淳化县| 华宁县| 河间市| 图木舒克市| 吉安县| 买车| 民县| 格尔木市| 凤翔县| 通山县| 轮台县| 新化县| 健康| 诸暨市| 汝州市| 和平区| 金沙县| 鄂州市| 新沂市| 偃师市| 绍兴市| 大同县| 洞头县| 金沙县|