SqlSugar ORM框架安裝配置使用詳解
簡介
SqlSugar是一個輕量級、高性能的.NET ORM框架,由中國開發(fā)者維護(hù),專為簡化數(shù)據(jù)庫操作而設(shè)計。它支持多種數(shù)據(jù)庫,提供了豐富的功能和優(yōu)秀的性能表現(xiàn),是.NET開發(fā)中非常受歡迎的ORM選擇。
為什么選擇SqlSugar?
- 輕量級:框架體積小,啟動快速
- 高性能:優(yōu)化的SQL生成和執(zhí)行機制
- 易用性:簡潔的API設(shè)計,學(xué)習(xí)成本低
- 多數(shù)據(jù)庫支持:支持主流數(shù)據(jù)庫系統(tǒng)
- 中文文檔:完善的中文文檔和社區(qū)支持
特性與優(yōu)勢
核心特性
- 多數(shù)據(jù)庫支持
- SQL Server
- MySQL
- PostgreSQL
- Oracle
- SQLite
- 達(dá)夢數(shù)據(jù)庫
- 人大金倉等國產(chǎn)數(shù)據(jù)庫
- 豐富的查詢方式
- Lambda表達(dá)式查詢
- SQL語句查詢
- 存儲過程調(diào)用
- 動態(tài)查詢構(gòu)建
- 代碼生成功能
- 根據(jù)數(shù)據(jù)庫表生成實體類
- 自動生成倉儲層代碼
- 支持模板自定義
- 事務(wù)管理
- 自動事務(wù)管理
- 手動事務(wù)控制
- 分布式事務(wù)支持
性能優(yōu)勢
// 高性能的批量操作
var users = new List<User>();
for (int i = 0; i < 10000; i++)
{
users.Add(new User { Name = $"User{i}", Age = 20 + i % 50 });
}
// 批量插入,性能優(yōu)異
db.Insertable(users).ExecuteCommand();安裝與配置
NuGet包安裝
# 核心包 Install-Package SqlSugar # 特定數(shù)據(jù)庫擴展 Install-Package SqlSugar.SqlServer Install-Package SqlSugar.MySql Install-Package SqlSugar.PostgreSQL
基礎(chǔ)配置
using SqlSugar;
// 數(shù)據(jù)庫連接配置
var db = new SqlSugarClient(new ConnectionConfig()
{
ConnectionString = "Server=.;Database=TestDB;Trusted_Connection=true;",
DbType = DbType.SqlServer,
IsAutoCloseConnection = true, // 自動關(guān)閉連接
InitKeyType = InitKeyType.Attribute // 使用特性初始化
});
// 日志配置
db.Aop.OnLogExecuting = (sql, pars) =>
{
Console.WriteLine($"SQL: {sql}");
Console.WriteLine($"Parameters: {string.Join(",", pars?.Select(p => $"{p.ParameterName}:{p.Value}"))}");
};多數(shù)據(jù)庫配置
var configs = new List<ConnectionConfig>
{
new ConnectionConfig
{
ConfigId = "db1",
ConnectionString = "SqlServer連接字符串",
DbType = DbType.SqlServer,
IsAutoCloseConnection = true
},
new ConnectionConfig
{
ConfigId = "db2",
ConnectionString = "MySQL連接字符串",
DbType = DbType.MySql,
IsAutoCloseConnection = true
}
};
var db = new SqlSugarScope(configs);
// 切換數(shù)據(jù)庫
var sqlServerDb = db.GetConnection("db1");
var mysqlDb = db.GetConnection("db2");基礎(chǔ)使用
實體類定義
[SugarTable("Users")]
public class User
{
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public int Id { get; set; }
[SugarColumn(Length = 50, IsNullable = false)]
public string Name { get; set; }
[SugarColumn(IsNullable = true)]
public int? Age { get; set; }
[SugarColumn(IsNullable = true)]
public DateTime? CreateTime { get; set; }
[SugarColumn(IsIgnore = true)] // 忽略該字段
public string TempProperty { get; set; }
}基本CRUD操作
// 插入
var user = new User { Name = "張三", Age = 25, CreateTime = DateTime.Now };
var id = db.Insertable(user).ExecuteReturnIdentity();
// 查詢
var users = db.Queryable<User>().ToList();
var user = db.Queryable<User>().Where(u => u.Id == 1).First();
// 更新
db.Updateable<User>()
.SetColumns(u => new User { Age = 26 })
.Where(u => u.Id == 1)
.ExecuteCommand();
// 刪除
db.Deleteable<User>().Where(u => u.Id == 1).ExecuteCommand();實體映射
特性配置
[SugarTable("tb_product")]
public class Product
{
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public int ProductId { get; set; }
[SugarColumn(ColumnName = "product_name", Length = 100)]
public string Name { get; set; }
[SugarColumn(ColumnName = "unit_price", DecimalDigits = 2)]
public decimal Price { get; set; }
[SugarColumn(ColumnName = "create_date", IsNullable = true)]
public DateTime? CreateDate { get; set; }
[SugarColumn(IsJson = true)] // JSON字段映射
public List<string> Tags { get; set; }
}Fluent API配置
db.CodeFirst.ConfigQuery<User>() .HasKey(u => u.Id) .HasIndex(u => u.Name, true) // 唯一索引 .HasColumn(u => u.Name, col => col.IsNullable(false).HasMaxLength(50)) .HasColumn(u => u.Age, col => col.IsNullable(true));
枚舉映射
public enum UserStatus
{
Active = 1,
Inactive = 0,
Deleted = -1
}
public class User
{
public int Id { get; set; }
public string Name { get; set; }
[SugarColumn(IsEnableUpdateVersionValidation = true)]
public UserStatus Status { get; set; }
}數(shù)據(jù)庫操作
數(shù)據(jù)庫初始化
// 創(chuàng)建數(shù)據(jù)庫
db.DbMaintenance.CreateDatabase();
// 根據(jù)實體創(chuàng)建表
db.CodeFirst.InitTables<User, Product, Order>();
// 檢查表是否存在
if (!db.DbMaintenance.IsAnyTable("Users"))
{
db.CodeFirst.InitTables<User>();
}表結(jié)構(gòu)管理
// 添加列
db.DbMaintenance.AddColumn("Users", new DbColumnInfo
{
DbColumnName = "Email",
DataType = "varchar",
Length = 100,
IsNullable = true
});
// 刪除列
db.DbMaintenance.DropColumn("Users", "TempColumn");
// 重命名表
db.DbMaintenance.RenameTable("OldTableName", "NewTableName");索引管理
// 創(chuàng)建索引
db.DbMaintenance.AddIndex("Users", new string[] { "Name", "Age" });
// 刪除索引
db.DbMaintenance.DropIndex("Users", "IX_Users_Name_Age");
// 獲取索引信息
var indexes = db.DbMaintenance.GetIndexList("Users");查詢操作
Lambda表達(dá)式查詢
// 基礎(chǔ)查詢
var users = db.Queryable<User>()
.Where(u => u.Age > 18)
.OrderBy(u => u.CreateTime)
.ToList();
// 復(fù)雜條件查詢
var result = db.Queryable<User>()
.Where(u => u.Name.Contains("張") && u.Age.HasValue)
.WhereIF(!string.IsNullOrEmpty(searchName), u => u.Name == searchName)
.Select(u => new
{
u.Id,
u.Name,
Age = u.Age ?? 0,
AgeGroup = u.Age > 30 ? "成年" : "青年"
})
.ToList();分頁查詢
// 方式一:使用ToPageList
int pageIndex = 1, pageSize = 10;
var pageResult = db.Queryable<User>()
.Where(u => u.Age > 18)
.OrderBy(u => u.Id)
.ToPageList(pageIndex, pageSize);
Console.WriteLine($"總記錄數(shù): {pageResult.TotalCount}");
Console.WriteLine($"總頁數(shù): {pageResult.TotalPages}");
// 方式二:使用ToOffsetPage
var offsetResult = db.Queryable<User>()
.Where(u => u.Age > 18)
.OrderBy(u => u.Id)
.ToOffsetPage(pageIndex, pageSize);聯(lián)表查詢
// 內(nèi)連接
var result = db.Queryable<User, Order>((u, o) => new JoinQueryInfos(
JoinType.Inner, u.Id == o.UserId))
.Select((u, o) => new
{
UserName = u.Name,
OrderId = o.Id,
OrderAmount = o.Amount
})
.ToList();
// 左連接
var leftJoinResult = db.Queryable<User>()
.LeftJoin<Order>((u, o) => u.Id == o.UserId)
.Select((u, o) => new
{
u.Name,
OrderCount = SqlFunc.IsNull(o.Id, 0)
})
.ToList();子查詢
// 子查詢示例
var subQuery = db.Queryable<Order>()
.Where(o => o.Status == OrderStatus.Completed)
.GroupBy(o => o.UserId)
.Select(o => new { UserId = o.UserId, TotalAmount = SqlFunc.Sum(o.Amount) });
var result = db.Queryable<User>()
.Where(u => SqlFunc.Subqueryable(subQuery)
.Where(s => s.UserId == u.Id && s.TotalAmount > 1000)
.Any())
.ToList();聚合查詢
// 分組聚合
var groupResult = db.Queryable<Order>()
.GroupBy(o => new { o.UserId, o.Status })
.Select(o => new
{
o.UserId,
o.Status,
Count = SqlFunc.Count(o.Id),
TotalAmount = SqlFunc.Sum(o.Amount),
AvgAmount = SqlFunc.Avg(o.Amount),
MaxAmount = SqlFunc.Max(o.Amount),
MinAmount = SqlFunc.Min(o.Amount)
})
.ToList();
// Having子句
var havingResult = db.Queryable<Order>()
.GroupBy(o => o.UserId)
.Having(o => SqlFunc.Sum(o.Amount) > 5000)
.Select(o => new
{
UserId = o.UserId,
TotalAmount = SqlFunc.Sum(o.Amount)
})
.ToList();高級功能
事務(wù)管理
// 自動事務(wù)
try
{
db.BeginTran();
// 執(zhí)行多個操作
db.Insertable(user).ExecuteCommand();
db.Updateable(order).ExecuteCommand();
db.Deleteable<Product>().Where(p => p.Id == 1).ExecuteCommand();
db.CommitTran();
}
catch (Exception ex)
{
db.RollbackTran();
throw;
}
// 使用using語句
using (var tran = db.UseTran())
{
db.Insertable(user).ExecuteCommand();
db.Updateable(order).ExecuteCommand();
tran.Complete(); // 提交事務(wù)
}批量操作
// 批量插入
var users = new List<User>();
for (int i = 0; i < 10000; i++)
{
users.Add(new User { Name = $"User{i}", Age = 20 + i % 50 });
}
// 高性能批量插入
db.Fastest<User>().BulkCopy(users);
// 批量更新
var updateUsers = db.Queryable<User>().Where(u => u.Age < 25).ToList();
updateUsers.ForEach(u => u.Age += 1);
db.Fastest<User>().BulkUpdate(updateUsers);
// 批量刪除
db.Deleteable<User>().Where(u => u.Age > 60).ExecuteCommand();緩存功能
// 查詢緩存
var cachedUsers = db.Queryable<User>()
.Where(u => u.Status == UserStatus.Active)
.WithCache(60) // 緩存60秒
.ToList();
// 自定義緩存鍵
var customCachedUsers = db.Queryable<User>()
.Where(u => u.Age > 18)
.WithCache("active_users", 300) // 自定義緩存鍵,緩存5分鐘
.ToList();
// 清除緩存
db.RemoveDataCache("active_users");讀寫分離
var configs = new List<ConnectionConfig>
{
new ConnectionConfig
{
ConfigId = "master",
ConnectionString = "主庫連接字符串",
DbType = DbType.SqlServer,
IsAutoCloseConnection = true
},
new ConnectionConfig
{
ConfigId = "slave1",
ConnectionString = "從庫1連接字符串",
DbType = DbType.SqlServer,
IsAutoCloseConnection = true,
SlaveConnectionConfigs = new List<SlaveConnectionConfig>
{
new SlaveConnectionConfig { HitRate = 50 }, // 50%命中率
}
}
};
var db = new SqlSugarScope(configs);
// 查詢自動使用從庫
var users = db.Queryable<User>().ToList();
// 強制使用主庫查詢
var masterUsers = db.GetConnection("master").Queryable<User>().ToList();多租戶支持
// 配置多租戶
db.SetTenantTable("tenant1", "Users_Tenant1");
db.SetTenantTable("tenant2", "Users_Tenant2");
// 切換租戶
db.ChangeTenant("tenant1");
var tenant1Users = db.Queryable<User>().ToList(); // 查詢Users_Tenant1表
db.ChangeTenant("tenant2");
var tenant2Users = db.Queryable<User>().ToList(); // 查詢Users_Tenant2表性能優(yōu)化
查詢優(yōu)化
// 1. 使用異步操作
var usersAsync = await db.Queryable<User>()
.Where(u => u.Age > 18)
.ToListAsync();
// 2. 只查詢需要的字段
var userNames = db.Queryable<User>()
.Select(u => u.Name)
.ToList();
// 3. 使用NoLock(SQL Server)
var noLockUsers = db.Queryable<User>()
.With(SqlWith.NoLock)
.ToList();
// 4. 分頁查詢大數(shù)據(jù)量
var largeDataPage = db.Queryable<User>()
.OrderBy(u => u.Id)
.ToOffsetPage(1, 1000);連接池優(yōu)化
var config = new ConnectionConfig
{
ConnectionString = "連接字符串",
DbType = DbType.SqlServer,
IsAutoCloseConnection = true,
// 連接池配置
ConfigureExternalServices = new ConfigureExternalServices
{
DataInfoCacheService = new HttpRuntimeCache(), // 使用緩存
SqlFuncServices = new List<SqlFuncExternal>() // 自定義SQL函數(shù)
},
// 性能配置
MoreSettings = new ConnMoreSettings
{
IsAutoRemoveDataCache = true, // 自動清理緩存
IsWithNoLockQuery = true, // 默認(rèn)使用NoLock
DefaultCacheDurationInSeconds = 600 // 默認(rèn)緩存時間
}
};SQL優(yōu)化建議
// 1. 避免N+1查詢問題
var usersWithOrders = db.Queryable<User>()
.Includes(u => u.Orders) // 一次性加載關(guān)聯(lián)數(shù)據(jù)
.ToList();
// 2. 使用批量操作代替循環(huán)
// 錯誤方式
foreach (var user in users)
{
db.Updateable(user).ExecuteCommand(); // N次數(shù)據(jù)庫訪問
}
// 正確方式
db.Updateable(users).ExecuteCommand(); // 1次數(shù)據(jù)庫訪問
// 3. 合理使用索引
var indexedQuery = db.Queryable<User>()
.Where(u => u.Email == "test@example.com") // 確保Email字段有索引
.First();最佳實踐
1. 倉儲模式實現(xiàn)
public interface IRepository<T> where T : class, new()
{
Task<T> GetByIdAsync(object id);
Task<List<T>> GetAllAsync();
Task<bool> InsertAsync(T entity);
Task<bool> UpdateAsync(T entity);
Task<bool> DeleteAsync(object id);
}
public class Repository<T> : IRepository<T> where T : class, new()
{
private readonly ISqlSugarClient _db;
public Repository(ISqlSugarClient db)
{
_db = db;
}
public async Task<T> GetByIdAsync(object id)
{
return await _db.Queryable<T>().InSingleAsync(id);
}
public async Task<List<T>> GetAllAsync()
{
return await _db.Queryable<T>().ToListAsync();
}
public async Task<bool> InsertAsync(T entity)
{
return await _db.Insertable(entity).ExecuteCommandAsync() > 0;
}
public async Task<bool> UpdateAsync(T entity)
{
return await _db.Updateable(entity).ExecuteCommandAsync() > 0;
}
public async Task<bool> DeleteAsync(object id)
{
return await _db.Deleteable<T>().In(id).ExecuteCommandAsync() > 0;
}
}2. 依賴注入配置
// Startup.cs 或 Program.cs
services.AddSingleton<ISqlSugarClient>(provider =>
{
var config = new ConnectionConfig
{
ConnectionString = Configuration.GetConnectionString("DefaultConnection"),
DbType = DbType.SqlServer,
IsAutoCloseConnection = true,
InitKeyType = InitKeyType.Attribute
};
var db = new SqlSugarClient(config);
// 配置日志
db.Aop.OnLogExecuting = (sql, pars) =>
{
var logger = provider.GetService<ILogger<SqlSugarClient>>();
logger.LogInformation($"SQL: {sql}");
};
return db;
});
services.AddScoped(typeof(IRepository<>), typeof(Repository<>));3. 配置管理
public class DatabaseOptions
{
public string ConnectionString { get; set; }
public string DbType { get; set; }
public bool EnableLogging { get; set; }
public int CommandTimeout { get; set; } = 30;
}
// appsettings.json
{
"Database": {
"ConnectionString": "Server=.;Database=TestDB;Trusted_Connection=true;",
"DbType": "SqlServer",
"EnableLogging": true,
"CommandTimeout": 60
}
}
// 配置使用
services.Configure<DatabaseOptions>(Configuration.GetSection("Database"));4. 異常處理
public class DatabaseExceptionHandler
{
private readonly ILogger<DatabaseExceptionHandler> _logger;
public DatabaseExceptionHandler(ILogger<DatabaseExceptionHandler> logger)
{
_logger = logger;
}
public async Task<T> ExecuteWithRetryAsync<T>(Func<Task<T>> operation, int maxRetries = 3)
{
for (int i = 0; i < maxRetries; i++)
{
try
{
return await operation();
}
catch (Exception ex) when (i < maxRetries - 1)
{
_logger.LogWarning($"數(shù)據(jù)庫操作失敗,正在重試... 第{i + 1}次,異常: {ex.Message}");
await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, i))); // 指數(shù)退避
}
}
return await operation(); // 最后一次嘗試,如果失敗則拋出異常
}
}5. 單元測試
[TestClass]
public class UserRepositoryTests
{
private ISqlSugarClient _db;
private IRepository<User> _userRepository;
[TestInitialize]
public void Setup()
{
var config = new ConnectionConfig
{
ConnectionString = "測試數(shù)據(jù)庫連接字符串",
DbType = DbType.Sqlite,
IsAutoCloseConnection = true
};
_db = new SqlSugarClient(config);
_db.CodeFirst.InitTables<User>();
_userRepository = new Repository<User>(_db);
}
[TestMethod]
public async Task InsertUser_ShouldReturnTrue()
{
// Arrange
var user = new User { Name = "測試用戶", Age = 25 };
// Act
var result = await _userRepository.InsertAsync(user);
// Assert
Assert.IsTrue(result);
Assert.IsTrue(user.Id > 0);
}
[TestCleanup]
public void Cleanup()
{
_db?.Dispose();
}
}總結(jié)
SqlSugar是一個功能強大、性能優(yōu)異的.NET ORM框架,具有以下優(yōu)勢:
主要優(yōu)點
- 易于學(xué)習(xí):簡潔的API設(shè)計,完善的中文文檔
- 高性能:優(yōu)化的SQL生成和執(zhí)行機制
- 功能豐富:支持多種數(shù)據(jù)庫操作和高級功能
- 靈活配置:支持多種配置方式和擴展點
- 活躍社區(qū):持續(xù)更新和維護(hù),社區(qū)支持良好
適用場景
- 中小型項目:快速開發(fā),簡單易用
- 高性能要求:批量操作,緩存支持
- 多數(shù)據(jù)庫環(huán)境:跨數(shù)據(jù)庫平臺開發(fā)
- 國產(chǎn)化項目:支持國產(chǎn)數(shù)據(jù)庫
注意事項
- 版本選擇:根據(jù)項目需求選擇合適的版本
- 性能監(jiān)控:合理使用日志和監(jiān)控功能
- 安全考慮:注意SQL注入防護(hù)和權(quán)限控制
- 測試覆蓋:編寫充分的單元測試和集成測試
SqlSugar為.NET開發(fā)者提供了一個優(yōu)秀的數(shù)據(jù)訪問解決方案,通過合理使用其功能特性,可以大大提高開發(fā)效率和應(yīng)用性能。在實際項目中,建議結(jié)合具體業(yè)務(wù)需求,選擇合適的功能和配置,以達(dá)到最佳的開發(fā)體驗和運行效果。
到此這篇關(guān)于SqlSugar ORM框架安裝配置使用詳解的文章就介紹到這了,更多相關(guān)SqlSugar ORM框架內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
為TextBox裝飾水印與(blur和focus)事件應(yīng)用
為了界面的美觀,有些時候可能需要為文本框(TextBox)裝飾個水??;它有兩種狀態(tài),一是blur和focus。因此,我們可以在Javascript寫兩個事件,感興趣的朋友可以了解下2013-01-01
asp.net下常用的加密算法MD5、SHA-1應(yīng)用代碼
在進(jìn)行軟件開發(fā)的過程中,為了提高系統(tǒng)的安全性能,經(jīng)常需要進(jìn)行敏感信息的加密處理。特別是在密碼儲存、文件傳輸、頁面?zhèn)髦档确矫?,對信息進(jìn)行加密顯得十分必要。下面介紹我們常用的兩種加密算法MD5、SHA1。2008-09-09
asp.net中一次性動態(tài)綁定多個droplistdown
asp.net中一次性動態(tài)綁定多個droplistdown的實現(xiàn)代碼,需要的朋友可以參考下。2011-10-10
ASP.NET下使用xml反序列化、緩存依賴實現(xiàn)個性化配置文件的實時生效
本文主要介紹了ASP.NET下使用xml反序列化、緩存依賴實現(xiàn)個性化配置文件的實時生效的方法。具有一定的參考價值,下面跟著小編一起來看下吧2017-01-01
利用ASP.NET MVC+EasyUI+SqlServer搭建企業(yè)開發(fā)框架
本文主要介紹使用asp.net mvc4、sqlserver、jquery2.0和easyui1.4.5搭建企業(yè)級開發(fā)框架的過程,希望能夠幫到大家。2016-04-04
解析ASP.NET?Core中Options模式的使用及其源碼
這篇文章主要介紹了ASP.NET?Core中Options模式的使用及其源碼解析,在ASP.NET Core中引入了Options這一使用配置方式,其主要是為了解決依賴注入時需要傳遞指定數(shù)據(jù)問題(不是自行獲取,而是能集中配置),需要的朋友可以參考下2022-03-03

