使用SqlSugar进行动态创建和操作表--CRUD
在SqlSugar中动态创建表和进行CRUD操作,可以通过以下步骤实现。这里使用动态对象(ExpandoObject)或字典表示数据,并使用动态表名进行操作:
1. 安装SqlSugar
Install-Package SqlSugar
2. 动态创建表与CRUD示例
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
public class DynamicTableService
{
private readonly SqlSugarClient _db;
public DynamicTableService(string connectionString)
{
_db = new SqlSugarClient(new ConnectionConfig()
{
ConnectionString = connectionString,
DbType = DbType.SqlServer, // 根据数据库修改(支持MySQL、SQLite等)
IsAutoCloseConnection = true,
});
// 初始化ORM配置
_db.Aop.OnLogExecuting = (sql, pars) => Console.WriteLine(sql);
}
// 动态创建表(若不存在)
public void CreateTableIfNotExists(string tableName, List<TableColumn> columns)
{
// 生成动态类型(通过反射Emit创建)
var entityType = DynamicTypeBuilder.CreateType(columns);
// 使用CodeFirst同步表结构
_db.CodeFirst.InitTables(entityType); // 自动根据类名建表
// 如果表名需要自定义(与类名不同),需添加特性 [SugarTable("TableName")]
}
// 插入数据
public int Insert(string tableName, ExpandoObject entity)
{
return _db.InsertableByObject(entity).AS(tableName).ExecuteCommand();
}
// 批量插入
public int InsertRange(string tableName, List<ExpandoObject> entities)
{
return _db.InsertableByObject(entities).AS(tableName).ExecuteCommand();
}
// 更新数据
public int Update(string tableName, ExpandoObject entity, string primaryKey = "Id")
{
dynamic expando = entity;
var id = ((IDictionary<string, object>)entity)[primaryKey];
return _db.UpdateableByObject(entity)
.AS(tableName)
.WhereColumns(primaryKey, id.ToString())
.ExecuteCommand();
}
// 删除数据(根据主键)
public int Delete(string tableName, object primaryKeyValue, string primaryKey = "Id")
{
return _db.Deleteable<object>()
.AS(tableName)
.Where($"{primaryKey} = @id", new { id = primaryKeyValue })
.ExecuteCommand();
}
// 查询所有数据
public List<ExpandoObject> GetAll(string tableName)
{
return _db.Queryable<ExpandoObject>().AS(tableName).ToList();
}
// 条件查询
public List<ExpandoObject> Where(string tableName, string whereSql, object parameters = null)
{
return _db.Queryable<ExpandoObject>().AS(tableName).Where(whereSql, parameters).ToList();
}
}
// 列定义结构
public class TableColumn
{
public string Name { get; set; }
public Type Type { get; set; } // 如:typeof(int), typeof(string)
public bool IsPrimaryKey { get; set; } = false;
public bool IsIdentity { get; set; } = false;
}
// 动态类型生成工具(通过反射Emit)
public static class DynamicTypeBuilder
{
public static Type CreateType(List<TableColumn> columns)
{
var typeBuilder = DynamicModule.CreateTypeBuilder();
foreach (var col in columns)
{
DynamicModule.CreateProperty(typeBuilder, col.Name, col.Type);
// 添加主键和自增特性
if (col.IsPrimaryKey)
{
typeBuilder.AddSugarPrimaryKey(col.Name, col.IsIdentity);
}
}
return typeBuilder.CreateType();
}
}
// 动态构建模块
public static class DynamicModule
{
private static readonly System.Reflection.Emit.ModuleBuilder _moduleBuilder;
static DynamicModule()
{
var assemblyName = new System.Reflection.AssemblyName("DynamicTypes");
var assemblyBuilder = System.Reflection.Emit.AssemblyBuilder.DefineDynamicAssembly(
assemblyName, System.Reflection.Emit.AssemblyBuilderAccess.Run);
_moduleBuilder = assemblyBuilder.DefineDynamicModule("DynamicModule");
}
public static System.Reflection.Emit.TypeBuilder CreateTypeBuilder()
{
string typeName = "DynamicType_" + Guid.NewGuid().ToString("N");
return _moduleBuilder.DefineType(typeName, System.Reflection.TypeAttributes.Public);
}
public static void CreateProperty(System.Reflection.Emit.TypeBuilder typeBuilder, string name, Type type)
{
var fieldBuilder = typeBuilder.DefineField("_" + name, type, System.Reflection.FieldAttributes.Private);
var propertyBuilder = typeBuilder.DefineProperty(
name,
System.Reflection.PropertyAttributes.None,
type,
Type.EmptyTypes);
var getMethod = typeBuilder.DefineMethod(
"get_" + name,
System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.SpecialName,
type,
Type.EmptyTypes);
var getIL = getMethod.GetILGenerator();
getIL.Emit(System.Reflection.Emit.OpCodes.Ldarg_0);
getIL.Emit(System.Reflection.Emit.OpCodes.Ldfld, fieldBuilder);
getIL.Emit(System.Reflection.Emit.OpCodes.Ret);
var setMethod = typeBuilder.DefineMethod(
"set_" + name,
System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.SpecialName,
null,
new[] { type });
var setIL = setMethod.GetILGenerator();
setIL.Emit(System.Reflection.Emit.OpCodes.Ldarg_0);
setIL.Emit(System.Reflection.Emit.OpCodes.Ldarg_1);
setIL.Emit(System.Reflection.Emit.OpCodes.Stfld, fieldBuilder);
setIL.Emit(System.Reflection.Emit.OpCodes.Ret);
propertyBuilder.SetGetMethod(getMethod);
propertyBuilder.SetSetMethod(setMethod);
}
public static void AddSugarPrimaryKey(
this System.Reflection.Emit.TypeBuilder typeBuilder,
string propertyName,
bool isIdentity)
{
// 为属性添加 [SugarColumn(IsPrimaryKey=true, IsIdentity=true)] 特性
var attrType = typeof(SugarColumn);
var ctor = attrType.GetConstructor(new Type[] { });
var builder = new System.Reflection.Emit.CustomAttributeBuilder(
ctor, new object[] { },
new[] { typeof(SugarColumn).GetProperty("IsPrimaryKey") },
new object[] { true },
new[] { typeof(SugarColumn).GetProperty("IsIdentity") },
new object[] { isIdentity }
);
typeBuilder.DefineProperty(
propertyName,
System.Reflection.PropertyAttributes.None,
null, null)
.SetCustomAttribute(builder);
}
}
使用示例
var service = new DynamicTableService("YourConnectionString");
// 定义动态表结构
var columns = new List<TableColumn>
{
new TableColumn { Name = "Id", Type = typeof(int), IsPrimaryKey = true, IsIdentity = true },
new TableColumn { Name = "Name", Type = typeof(string) },
new TableColumn { Name = "Age", Type = typeof(int) }
};
// 创建表(自动根据类名同步表结构)
service.CreateTableIfNotExists("DynamicPerson", columns);
// 插入数据
dynamic data = new ExpandoObject();
data.Name = "Alice";
data.Age = 30;
service.Insert("DynamicPerson", data);
// 查询
var allData = service.GetAll("DynamicPerson");
foreach (dynamic item in allData)
{
Console.WriteLine($"Id: {item.Id}, Name: {item.Name}");
}
// 条件查询
var adults = service.Where("DynamicPerson", "Age > @age", new { age = 18 });
关键说明
-
动态表创建
- 使用
DynamicTypeBuilder运行时生成实体类。 - 通过
db.CodeFirst.InitTables(type)同步表结构。
- 使用
-
动态CRUD
- 插入:
InsertableByObject+AS(tableName) - 查询:
Queryable<ExpandoObject>()+AS(tableName) - 支持动态条件拼接(
Where中使用参数化SQL避免注入)。
- 插入:
-
注意事项
- 不同数据库(如MySQL/SQLite)需修改
DbType。 - 主键自增需在列定义中设置
IsIdentity=true。 - 实际生产环境中建议添加异常处理和事务。
- 不同数据库(如MySQL/SQLite)需修改
-
高级场景
- 动态修改表结构:使用
db.DbMaintenance操作DDL语句。 - 分表分库:结合
SplitTable功能实现(需额外配置)。
- 动态修改表结构:使用
通过这种方式,你可以在SqlSugar中灵活操作动态生成的表结构并执行CRUD操作。

浙公网安备 33010602011771号