using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using XKJ.Communication.Wrap.Models;
namespace RandomLib.Infrastructure
{
public class SqliteRfidContext : DbContext
{
public DbSet<RfidReaderPos> Readers { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite("Data Source=rfid.db");
}
}
public class SqliteRfidRepository : IRfidRepository
{
private readonly SqliteRfidContext _context;
public SqliteRfidRepository(SqliteRfidContext context) => _context = context;
public async Task<List<RfidReaderPos>> GetAllAsync() => await _context.Readers.Include(r => r.PlcPoints).ToListAsync();
public async Task<RfidReaderPos> GetByCodeAsync(string code) =>
await _context.Readers.Include(r => r.PlcPoints).FirstOrDefaultAsync(r => r.RfidCode == code);
public async Task AddAsync(RfidReaderPos model)
{
await _context.Readers.AddAsync(model);
await _context.SaveChangesAsync();
}
public async Task UpdateAsync(RfidReaderPos model)
{
_context.Readers.Update(model);
await _context.SaveChangesAsync();
}
public async Task DeleteAsync(string code)
{
var reader = await GetByCodeAsync(code);
if (reader != null)
{
_context.Readers.Remove(reader);
await _context.SaveChangesAsync();
}
}
public async Task<PaginatedResult<RfidReaderPos>> GetPagedAsync(int page, int pageSize)
{
var total = await _context.Readers.CountAsync();
var items = await _context.Readers
.Include(r => r.PlcPoints)
.Skip((page - 1) * pageSize)
.Take(pageSize)
.ToListAsync();
return new PaginatedResult<RfidReaderPos>
{
Items = items,
TotalCount = total,
PageNumber = page,
PageSize = pageSize
};
}
}
}
改用 public class SqliteDBHelper : IDisposable
{
#region 基础参数
public static JsonSerializerSettings settings = new JsonSerializerSettings
{
ContractResolver =
new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver()
};
private readonly SqliteConnectionStringBuilder _connStr;
public string ConnStr => _connStr.ConnectionString;
private SqliteConnection _connection;
#endregion
#region 构造函数
public SqliteDBHelper(string connectionString)
{
if (string.IsNullOrEmpty(connectionString))
throw new ArgumentException("连接字符串不能为空");
_connStr = new SqliteConnectionStringBuilder(connectionString);
_connection = new SqliteConnection(_connStr.ConnectionString);
}
public SqliteDBHelper(string sqliteFilePathAndName, SqliteOpenMode mode, SqliteCacheMode cacheMode,
int defaultTimeout = 30, bool isUseSharePool = true)
{
_connStr = new SqliteConnectionStringBuilder
{
DataSource = sqliteFilePathAndName,
Mode = mode,
Cache = cacheMode,
//Pooling = isUseSharePool
};
_connection = new SqliteConnection(_connStr.ConnectionString);
}
public SqliteDBHelper(string sqliteFilePathAndName, string password, SqliteOpenMode mode, SqliteCacheMode cacheMode,
int defaultTimeout = 30, bool isUseSharePool = true)
{
_connStr = new SqliteConnectionStringBuilder
{
DataSource = sqliteFilePathAndName,
Password = password,
Mode = mode,
Cache = cacheMode,
Pooling = isUseSharePool
};
_connection = new SqliteConnection(_connStr.ConnectionString);
}
#endregion
#region 数据库管理
private static SqliteDBHelper _instance = null;
/// <summary>
/// 单例模式
/// </summary>
public static SqliteDBHelper Instance
{
get
{
if (_instance == null)
{
var builder = new SqliteConnectionStringBuilder
{
DataSource = "mydatabase.db",
Mode = SqliteOpenMode.ReadWriteCreate
};
SqliteDBHelper sqliteDBHelper = new SqliteDBHelper(builder.ToString());
sqliteDBHelper.Open();
_instance = sqliteDBHelper;
}
return _instance;
}
}
public void Open() => _connection.Open();
public void ExecuteNonQuery(string sql)
{
using var command = _connection.CreateCommand();
command.CommandText = sql;
command.ExecuteNonQuery();
}
public void Dispose() => _connection?.Dispose();
public ResultInfo CreateSqliteDatabase(string sqliteFilePathAndName)
{
var result = new ResultInfo();
try
{
if (File.Exists(sqliteFilePathAndName))
{
result.SetError($"{sqliteFilePathAndName} 文件已存在!");
return result;
}
string folder = Path.GetDirectoryName(sqliteFilePathAndName);
if (!Directory.Exists(folder)) Directory.CreateDirectory(folder);
using var connection = new SqliteConnection(_connStr.ConnectionString);
//_connection = new SqliteConnection(_connStr.ConnectionString);
//connection.Open();
result.SetSuccess($"{sqliteFilePathAndName} 创建成功");
}
catch (Exception ex)
{
result.SetError(ex.Message);
}
return result;
}
public ResultInfo ModifyDatabasePassword(string oldPassword, string newPassword)
{
var result = new ResultInfo();
try
{
var builder = new SqliteConnectionStringBuilder(ConnStr)
{
Password = oldPassword
};
using var conn = new SqliteConnection(builder.ConnectionString);
conn.Open();
using var cmd = conn.CreateCommand();
cmd.CommandText = "SELECT quote($newPassword)";
cmd.Parameters.AddWithValue("$newPassword", newPassword);
var quotedNewPassword = (string)cmd.ExecuteScalar();
cmd.CommandText = $"PRAGMA rekey = {quotedNewPassword}";
cmd.ExecuteNonQuery();
_connStr.Password = newPassword;
conn.Dispose();
result.SetSuccess("密码修改成功");
}
catch (Exception ex)
{
result.SetError($"修改密码失败: {ex.Message}");
}
return result;
}
public ResultInfo CreateTable(string tableName, List<SqliteFieldInfo> fieldList)
{
var result = new ResultInfo();
if (string.IsNullOrEmpty(tableName) || fieldList == null || fieldList.Count == 0)
{
result.SetError("表名或字段列表为空");
return result;
}
var sb = new StringBuilder();
sb.Append($"CREATE TABLE IF NOT EXISTS {tableName} ( \n");
for (int i = 0; i < fieldList.Count; i++)
{
var field = fieldList[i];
sb.Append(FormatField(field));
if (i < fieldList.Count - 1) sb.Append(",\n");
}
sb.Append("\n);");
try
{
using var conn = new SqliteConnection(ConnStr);
conn.Execute(sb.ToString());
result.SetSuccess($"表 {tableName} 创建成功");
}
catch (Exception ex)
{
result.SetError($"创建表失败: {ex.Message}");
}
return result;
}
public ResultInfo DropTable(string tableName )
{
var result = new ResultInfo();
if (string.IsNullOrEmpty(tableName) )
{
result.SetError("表名或字段列表为空");
return result;
}
var sb = new StringBuilder();
sb.Append($"DROP TABLE {tableName} \n");
try
{
using var conn = new SqliteConnection(ConnStr);
conn.Execute(sb.ToString());
result.SetSuccess($"表 {tableName} drop成功");
}
catch (Exception ex)
{
result.SetError($"drop表失败: {ex.Message}");
}
return result;
}
private string FormatField(SqliteFieldInfo field)
{
if (field == null) return "";
var sb = new StringBuilder();
sb.Append($"{field.Name} {field.DataType}");
if (field.Length > 0)
sb.Append($"({field.Length})");
if (field.IsNotEmpty) sb.Append(" NOT NULL");
if (field.IsPrimaryKey) sb.Append(" PRIMARY KEY");
if (field.IsAutoIncrement) sb.Append(" AUTOINCREMENT");
return sb.ToString();
}
#endregion
#region CRUD 操作
public IDbConnection GetOpenConnection()
{
var conn = new SqliteConnection(ConnStr);
conn.Open();
return conn;
}
public int ExecuteNonQuery(string sql, Dictionary<string, object> parameters)
{
using var conn = GetOpenConnection();
using var cmd = new SqliteCommand(sql, (SqliteConnection?)conn);
foreach (var param in parameters)
{
cmd.Parameters.AddWithValue(param.Key, param.Value);
}
return cmd.ExecuteNonQuery();
}
// 创建索引的扩展方法
public void CreateIndex<T>(string columnName)
{
var tableName = typeof(T).Name;
var sql = $"CREATE INDEX IF NOT EXISTS idx_{tableName}_{columnName} ON {tableName}({columnName})";
ExecuteNonQuery(sql, new Dictionary<string, object>());
}
// 通用插入方法
/// <summary>
/// 插入一条记录
/// </summary>
public int Insert<T>(T entity)
{
var propsraw = typeof(T).GetProperties();
var props = new List<PropertyInfo>(propsraw.Length);
foreach(var prop in propsraw) {
var sqliteAttr = prop.GetCustomAttribute<SqliteField>();
if (sqliteAttr == null || !sqliteAttr.Ignore)
{
props.Add(prop);
}
}
var columns = string.Join(",", props.Select(p => p.Name));
var values = string.Join(",", props.Select(p => $"@{p.Name}"));
var sql = $"INSERT INTO {typeof(T).Name}({columns}) VALUES({values})";
var parameters = props.ToDictionary(p => $"@{p.Name}", p => p.GetValue(entity));
return ExecuteNonQuery(sql, parameters);
}
///// <summary>
///// 更新一条记录
///// </summary>
//public bool Update<T>(T entity)
//{
// using var conn = GetOpenConnection();
// return conn.Update(entity);
//}
///// <summary>
///// 删除一条记录
///// </summary>
//public bool Delete<T>(T entity)
//{
// using var conn = GetOpenConnection();
// return conn.Delete(entity);
//}
public int Update(string tableName, Dictionary<string, object> setValues,
Dictionary<string, object> whereConditions)
{
var setClause = string.Join(",", setValues.Keys.Select(k => $"{k} = ${k}"));
var whereClause = string.Join(" AND ", whereConditions.Keys.Select(k => $"{k} = ${k}"));
var sql = $"UPDATE {tableName} SET {setClause} WHERE {whereClause}";
using var conn = GetOpenConnection();
using var cmd = new SqliteCommand(sql, (SqliteConnection?)conn);
foreach (var param in setValues.Concat(whereConditions))
{
cmd.Parameters.AddWithValue($"${param.Key}", param.Value); // 关键点:参数前缀$
}
return cmd.ExecuteNonQuery();
}
public int SafeUpdate(string tableName, Dictionary<string, object> setValues,
Dictionary<string, object> whereConditions, int retryCount = 3)
{
for (int i = 0; i < retryCount; i++)
{
try
{
return Update(tableName, setValues, whereConditions);
}
catch (SqliteException ex) when (ex.SqliteErrorCode == 5)
{
if (i == retryCount - 1) throw;
Thread.Sleep(100 * (i + 1));
}
}
return 0;
}
public int DeleteWithTransaction(string tableName, Dictionary<string, object> conditions)
{
using var conn = GetOpenConnection();
using var transaction = conn.BeginTransaction();
try
{
var whereClause = string.Join(" AND ", conditions.Keys.Select(k => $"{k} = ${k}"));
var sql = $"DELETE FROM {tableName} WHERE {whereClause}";
using var cmd = new SqliteCommand(sql, (SqliteConnection?)conn, (SqliteTransaction?)transaction);
foreach (var param in conditions)
{
cmd.Parameters.AddWithValue($"${param.Key}", param.Value);
}
int result = cmd.ExecuteNonQuery();
transaction.Commit();
return result;
}
catch (SqliteException ex) when (ex.SqliteErrorCode == 5) // SQLITE_BUSY
{
transaction.Rollback();
Thread.Sleep(100);
return DeleteWithTransaction(tableName, conditions); // 递归重试
}
}
/// <summary>
/// 查询所有记录
/// </summary>
public IEnumerable<T> QueryAll<T>() where T : class
{
using var conn = GetOpenConnection();
return conn.Query<T>("SELECT * FROM " + typeof(T).Name);
}
/// <summary>
/// 根据条件查询
/// </summary>
public IEnumerable<T> Query<T>(string sql, object param = null)
{
using var conn = GetOpenConnection();
return conn.Query<T>(sql, param);
}
/// <summary>
/// 分页查询
/// </summary>
public IEnumerable<T> QueryPaged<T>(int page, int pageSize, out int totalCount)
{
var tableName = typeof(T).Name;
var offset = (page - 1) * pageSize;
using var conn = GetOpenConnection();
var items = conn.Query<T>($"SELECT * FROM {tableName} LIMIT @limit OFFSET @offset",
new { limit = pageSize, offset = offset });
totalCount = conn.ExecuteScalar<int>($"SELECT COUNT(*) FROM {tableName}");
return items;
}
public List<SqliteFieldInfo> GenerateFieldInfo<T>()
{
var fieldList = new List<SqliteFieldInfo>();
foreach (var prop in typeof(T).GetProperties())
{
var field = new SqliteFieldInfo { Name = prop.Name };
// 解析数据类型
field.DataType = prop.PropertyType switch
{
var t when t == typeof(int) => "INTEGER",
var t when t == typeof(string) => "TEXT",
var t when t == typeof(double) => "REAL",
_ => "BLOB"
};
// 处理注解
var sqliteAttr = prop.GetCustomAttribute<SqliteField>();
if (sqliteAttr != null && sqliteAttr.Ignore)
{
continue;
}
var maxLenAttr = prop.GetCustomAttribute<MaxLengthAttr>();
var pkAttr = prop.GetCustomAttribute<PrimaryKey>();
field.IsPrimaryKey = pkAttr != null;//|| (sqliteAttr?.IsPrimaryKey ?? false)
field.IsAutoIncrement = sqliteAttr?.AutoIncrement ?? false;
field.IsNotEmpty = sqliteAttr?.NotNull ?? false;
field.Length = maxLenAttr?.Length ?? sqliteAttr?.Length ?? 0;
fieldList.Add(field);
}
return fieldList;
}
} 实现
最新发布