JCoder.Db4Net
3.2621.1
dotnet add package JCoder.Db4Net --version 3.2621.1
NuGet\Install-Package JCoder.Db4Net -Version 3.2621.1
<PackageReference Include="JCoder.Db4Net" Version="3.2621.1" />
<PackageVersion Include="JCoder.Db4Net" Version="3.2621.1" />
<PackageReference Include="JCoder.Db4Net" />
paket add JCoder.Db4Net --version 3.2621.1
#r "nuget: JCoder.Db4Net, 3.2621.1"
#:package JCoder.Db4Net@3.2621.1
#addin nuget:?package=JCoder.Db4Net&version=3.2621.1
#tool nuget:?package=JCoder.Db4Net&version=3.2621.1
JCoder.Db4Net
| 属性 | |
|---|---|
| 作者(Authors) | Jackie Law |
| 版权(Copyright) | Copyright © Jackie Law. All rights reserved. |
| 协议 | MIT |
| 联系(QQ) | 1378071853 |
| 联系(Wechat) | JackieLaw1024 |
| 联系(Email) | JackieLaw-dev@outlook.com |
一.架构说明
| JCoder.Db4Net | |
|---|---|
| 语言 | C# |
| 协议 | MIT |
| .Net框架 | .Net Standard2.1; .Net Framework 4.7.2; .Net 6; .Net 8; .Net 10; |
| 简述 | Database类库,一款为方便使用数据库的操作类库。 |
1.1 引用类库
| 引用类库 | 版本 |
|---|---|
| - | - |
1.2 相关类库
| 相关类库 | 说明 |
|---|---|
| JCoder | JCoder库系列的基础库,聚焦于C#的扩展。 |
| JCoder.Data | 一款通用的数据对象库。 |
| JCoder.Db4Net.MySql | 一个基于JCoder.Db4Net且支持MySql的库。 |
| JCoder.Db4Net.Sqlite | 一个基于JCoder.Db4Net且支持Sqlite的库。 |
| JCoder.Db4Net.SqlServer | 一个基于JCoder.Db4Net且支持SqlServer的库。 |
二.获取方式
- 版本要求:>=3.17.1
- 以版本3.17.1为例
| 获取方式 | 描述 |
|---|---|
| Package Manager | Install-Package JCoder.Db4Net -Version 3.17.1 |
| .Net CLI | dotnet add package JCoder.Db4Net --version 3.17.1 |
| PackageReference | <PackageReference Include="JCoder.Db4Net" Version="3.17.1" /> |
| Paket CLI | paket add JCoder.Db4Net --version 3.17.1 |
| Script&Interactive | #r "nuget: JCoder.Db4Net, 3.17.1" |
| Cake | // Install as a Cake Addin<br/>#addin nuget:?package=JCoder.Db4Net&version=3.17.1<br/><br/>// Install as a Cake Tool<br/>#tool nuget:?package=JCoder.Db4Net&version=3.17.1 |
三.使用说明
3.1 主要类与接口
| 名称 | 类型 | 描述 |
|---|---|---|
| IDbSqlTexter | 接口 | 主要用于SQL语句的生成。 |
| IDbBuilder | 接口 | 主要用于数据库结构的处理。 |
| IDbOperator | 接口 | 主要用于SQL的执行与处理。 |
| IFactoryDbOperator | 接口 | 通过ProviderFactory方式,进行SQL的执行与处理。<br/>主要有以下实现:MsSqlFactoryOperator、SQLiteFactoryOperator 、MySqlFactoryOperator 。 |
| Db | 类 | 工具类,主要用于数据库通用的处理。 |
| Db | 类 | 工具类,主要用于数据库在数据对象上的通用处理。 |
| IDbExpresser | 接口 | 表达器基契约:Dber、Reset、UseParameter、ToExecuteArgument、ToSQL。 |
| IDbQueryExpresser | 接口 | 查询表达器契约:继承 IDbExpresser,补充 RunTo* 全套执行方法与 QueryDictionary、RunRowAsDictionary 等。DbSelectExpresser 与 DbQueryable 都实现该契约。 |
| DbSelectExpresser<TEntity> | 类 | 基于表达式的查询表达器(NewQuery 创建),实现 IDbQueryExpresser,支持 Where/OrderBy/Select/Limited/Paging 链。 |
| DbQueryable<TElement> | 类 | 类 Linq 的查询对象(From<TEntity>() 创建),实现 IQueryable<TElement> 与 IDbQueryExpresser,方法名与 System.Linq 一致,也能直接使用标准 Linq 扩展。 |
3.2特性说明
| Attribute类 | 应用位置 | 描述 |
|---|---|---|
| DbDatabaseAttribute | Class、Struct | 数据库的相关信息,可用于通过Entity进行CRUD。 |
| DbTableAttribute | Class、Struct | 数据库的数据表信息,可用于通过Entity进行CRUD。 |
| DbViewAttribute | Class、Struct | 数据库的视图信息,可用于通过Entity进行查询等操作。 |
| DbRefTableAttribute | Property | (未完成)关联的数据表信息,可用于通过Entity获取关联的副表数据。 |
| DbFieldAttribute | Property | 数据列信息,可用于通过Entity进行CRUD。 |
| DbFieldExtendAttribute | Property | 数据列的扩展信息。 |
| DbFieldPropertyAttribute | Property | 数据列的属性信息。 |
| DbNumberExtAttribute | Property | 数字型数据列的扩展信息。 |
| DbStringExtAttribute | Property | 文本型数据列的扩展信息。 |
| DbTimeExtAttribute | Property | 时间型数据列的扩展信息。 |
| DbAllowNullAttribute | Property | 数据列是否允许为Null值。 |
| DbAutoIncrementAttribute | Property | 数据列是否自动增长。 |
| DbPrimaryKeyAttribute | Property | 数据列是否为主键数据列。 |
| DbForeignKeyAttribute | Property | 数据列是否为外键数据列。 |
| DbGuidAttribute | Property | (未完成)数据列是否为GUID数据列。 |
| DbIndexAttribute | Property | 数据表的索引列信息。 |
| DbIndexFieldPropertyAttribute | Property | 数据表的索引列的扩展属性信息。 |
| DbIgnoreAttribute | Property | 进行与数据库相关的处理时,将忽略标记的字段与属性。 |
| DbIgnoreInsertAttribute | Property | 进行Insert处理时,将忽略标记的字段与属性。 |
| DbIgnoreUpdateAttribute | Property | 进行Update处理时,将忽略标记的字段与属性。 |
| EnumNameAttribute | Property | Entity数据转换为DataTable时,将枚举字段、属性转换为枚举名称的数据列。 |
| FieldRouteAttribute | Property | Entity数据转换为DataTable时,根据路径获取标记属性对象中的实例值。 |
| DbIgnoreConvertionAttribute | Property | Entity数据转换为DataTable时,将忽略标记的字段与属性。 |
| DbJsonAttribute | Property | (未完成)Entity数据转换为DataTable时,将字段、属性转换为Json格式的数据列。 |
| NameAttribute | Class、Struct、Property | 名称信息。可应用于以下情况,1.定义DataTable的数据列名称;2.定义DataTable的Table名称; |
| SortAttribute | Property | 排序信息。可用于Entity转换为DataTable时的DataColumn顺序。 |
3.3 函数名称说明
| 注意事项 | 描述 |
|---|---|
| 函数名称包含Entity或Entities | 属性数据处理以DbAttribute优先。 |
| 函数名称包含Object或Objects | 属性数据有多种处理方式。<br/>OnlyProperty方式直接忽略DbAttribute。<br/>OnlyDbAttribute方式只处理有DbAttribute的。<br/>DbAttributeFirst方式以DbAttribute优先。 |
4.1 创建实例-IDbOperator\IFactoryDbOperator
创建实例
// MySql, 需要先在项目里引用或加载MySql官方库MySql.Data.dll。 IDbOperator _dber = new MySqlFactoryOperator() { ConnectionString = "server=127.0.0.1;database=test;uid=user;pwd=testpassword;Connect Timeout=18000" }; // SQLite, 需要先在项目里引用或加载Sqlite官方库System.Data.SQLite.dll。 IDbOperator _dber = new SQLiteFactoryOperator() { ConnectionString = "Data Source=.\data\test.db3;" }; // Sql Server, 需要先在项目里引用或加载Sql Server官方库System.Data.SqlClient.dll。 IDbOperator _dber = new MsSqlFactoryOperator() { ConnectionString = "Server=127.0.0.1;Database=test;Uid = user; Pwd=testpassword;" };使用创建全局实例
// MySql IDbOperator _dber = Db.Hub.GetDberOrNew<MySqlFactoryOperator>(); _dber.ConnectionString = "server=127.0.0.1;database=test;uid=user;pwd=testpassword;Connect Timeout=18000";
4.2 IDbOperator使用
CanConnect(是否能够连接数据库)
// CanConnect(是否能够连接数据库) if (_dber.CanConnect()) { return; }CreateParameter(创建相应的参数)
// CreateParameter(创建相应的参数) return _dber.CreateParameter( "ID", 123);Execute(执行SQL)
// Execute(执行SQL) var _parameters = new List<DbParameter>() { _dber.CreateParameter("ID","ID123"), _dber.CreateParameter("Name","Name123"), _dber.CreateParameter("CreateTime",DateTime.Now), }; var _sql = @"insert table1 (ID,Name,CreateTime) values (@ID,@Name,@CreateTime);"; var _count = _dber.Execute(_sql, _parameters);//直接执行SQL //var _count = _dber.Execute(true,_sql, _parameters);// 使用事务执行SQL return _count >= 1;Execute(执行多条SQL)
// Execute(执行多条SQL) var _parameters = new List<DbParameter>() { _dber.CreateParameter("Value1","ID123"), _dber.CreateParameter("Value2","Name123"), _dber.CreateParameter("Value3","Name1456"), }; var _sqls = new string[] { @"insert table3 (Values) values (@Value1);", @"insert table3 (Values) values (@Value2);", @"insert table3 (Values) values (@Value3);", } ; var _count = _dber.Execute(_sqls, _parameters);//直接执行SQL //var _count = _dber.Execute(true, _sqls, _parameters);// 使用事务执行SQL return _count >= 1;ExecuteTransaction(使用事务执行指定的SQL)
// ExecuteTransaction(使用事务执行指定的SQL) public void ExecuteTransaction() { _dber.StartTransaction(); try { for (int i = 0; i < 3; i++) { var _parameters = new List<DbParameter>() { _dber.CreateParameter("ID",i.ToString()), _dber.CreateParameter("Name","Name123"), _dber.CreateParameter("CreateTime",DateTime.Now), }; var _sql = @"insert table1 (ID,Name,CreateTime) values (@ID,@Name,@CreateTime);"; var _isSucceed = _dber.ExecuteTransaction(_sql, _parameters); } } catch (Exception ex) { _dber.RollbackTransaction(); return; } _dber.FinishTransaction(); }ExecuteTransaction(使用指定的事务执行指定的SQL)
// ExecuteTransaction(使用指定的事务执行指定的SQL) public void ExecuteTransaction() { for (int i = 0; i < 3; i++) { var _key = "Transaction" + i.ToString(); _dber.StartTransaction(_key); var _id = i.ToString() + DateTime.Now.ToLongTimeString(); try { var _parameters = new List<DbParameter>() { _dber.CreateParameter("ID",_id), _dber.CreateParameter("Name","Name123"), _dber.CreateParameter("CreateTime",DateTime.Now), }; var _sql = @"insert table1 (ID,Name,CreateTime) values (@ID,@Name,@CreateTime);"; var _isSucceed = _dber.ExecuteTransaction(_key, _sql, _parameters); } catch (Exception ex) { _dber.RollbackTransaction(_key); return; } if (!_dber.FinishTransaction(_key)) { return; } } }RollbackTransaction(回滚指定的事务)
// RollbackTransaction(回滚指定的事务) public void RollbackTransaction() { var _key = "Transaction"; _dber.StartTransaction(_key); var _id = nameof(RollbackTransaction); try { var _parameters = new List<DbParameter>() { _dber.CreateParameter("ID",_id), _dber.CreateParameter("Name","Name123"), _dber.CreateParameter("CreateTime",DateTime.Now), }; var _sql = @"insert table1 (ID,Name,CreateTime) values (@ID,@Name,@CreateTime);"; var _isSucceed = _dber.ExecuteTransaction(_key, _sql, _parameters); } catch (Exception ex) { _dber.RollbackTransaction(_key); return; } _dber.RollbackTransaction(_key); }QueryTable(查询数据,并返回DataTable)
public DataTable QueryTable() { var _parameters = new List<DbParameter>() { _dber.CreateParameter("ID",123), }; var _sql = "select * from table1 where ID=@ID;"; return _dber.QueryTable(_sql, _parameters); }QueryTables(查询数据,并返回DataSet)
public DataSet QueryTables() { var _parameters = new List<DbParameter>() { _dber.CreateParameter("ID",123), }; var _sql = "select * from table1 where ID=@ID;"; _sql += "select * from table2 where ID=@ID;"; return _dber.QueryTables(_sql, _parameters); }QueryReader(查询数据,并返回DbDataReader)
public DbDataReader QueryReader()
{
var _parameters = new List<DbParameter>()
{
_dber.CreateParameter("ID",123),
};
var _sql = "select * from table1 where ID=@ID;";
return _dber.QueryReader(_sql, _parameters);
}
QueryDictionary (将查询结果的首两列数据转换为Dictionary)
public Dictionary<string, string> QueryDictionary()
{
var _sql = "select Key,Value from table1 ;";
return _dber.QueryDictionary<string, string>(_sql);
}
QueryRowAsDictionary (将查询结果的首行数据转换为Dictionary)
Dictionary<string, string> _dict = _dber.QueryRowAsDictionary("select * from table1 ;");
foreach (var kv in _dict)
{
Console.WriteLine($"[{kv.Key}]{kv.Value}");
}
// 输出 - 有数据时
// [Key001]00327d8c-ddcc-46cc-92d1-9f82dca9374e
// [Column001]阎臭潭
// [Column002]Thithea Tisasheet
// [Column003]2023-02-13 15:44:57.304646
// 输出 - 没有数据时
// [Key001]
// [Column001]
// [Column002]
// [Column003]
QueryValues (将查询结果的首列数据转换为List)
public List<string> QueryNames()
{
var _sql = "select Names from table1 ;";
return _dber.QueryValues<string>(_sql);
}
QueryValue (将查询值转换为long)
public long QueryValue()
{
var _sql = "select count(1) from table1 ;";
return _dber.QueryScalar<long>(_sql);
}
IsExistData (查询是否存在数据)
public bool IsExistData()
{
var _sql = "select 1 from table1 where id=1;";
return _dber.IsExistData(_sql);
}
4.3 IDbSqlTexter使用
生成实例
// 用于生成MySql语句,引用JCoder.Db4Net.MySql IDbSqlTexter _sqltexter = new MySqlTexter(); // 用于生成Sqlite语句,引用JCoder.Db4Net.Sqlite IDbSqlTexter _sqltexter = new SqliteTexter(); // 用于生成SqlServer语句,引用JCoder.Db4Net.SqlServer IDbSqlTexter _sqltexter = new MsSqlTexter();生成数据库相关的SQL语句
// 生成获取当前数据库信息的SQL语句 _sqltexter.GetDatabase(); // 生成获取指定数据库信息的SQL语句 _sqltexter.GetDatabase("database"); // 生成获取数据库信息列表的SQL语句 _sqltexter.GetDatabaseList(); // 生成创建数据库的SQL语句 _sqltexter.CreateDatabase("database"); // 生成删除数据库的SQL语句 _sqltexter.DeleteDatabase("database");生成数据表(Table)相关的SQL语句
// 生成获取当前数据库的指定数据表的数据列信息的SQL语句 _sqltexter.GetTableColumns("table01"); // 生成获取指定数据库的指定数据表的数据列信息的SQL语句 _sqltexter.GetTableColumns("database","table01"); // 生成获取当前数据库的指定数据表信息的SQL语句SQL语句 _sqltexter.GetTable("table01"); // 生成获取当前数据库的指定数据表信息的SQL语句SQL语句 _sqltexter.GetTable("database","table01"); // 生成获取当前数据库的数据表列表的SQL语句 _sqltexter.GetTableList(); // 生成获取指定数据库的数据表列表的SQL语句 _sqltexter.GetTableList("database"); // 生成删除当前数据库的数据表的SQL语句 _sqltexter.DeleteTable("table01"); // 生成删除指定数据库的数据表的SQL语句 _sqltexter.DeleteTable("database","table01"); // 生成创建数据表的SQL语句 _sqltexter.CreateTable("table01", new List<DbColumn>()); // 生成创建数据表的SQL语句 _sqltexter.CreateTable("database", "table01", new List<DbColumn>());生成视图(View)相关的SQL语句
// 生成获取当前数据库的指定View的数据列信息的SQL语句 _sqltexter.GetViewColumns("view01"); // 生成获取指定数据库的指定View的数据列信息的SQL语句 _sqltexter.GetViewColumns("database","view01"); // 生成获取当前数据库的指定View信息的SQL语句SQL语句 _sqltexter.GetView("view01"); // 生成获取当前数据库的指定View信息的SQL语句SQL语句 _sqltexter.GetView("database","view01"); // 生成获取当前数据库的View列表的SQL语句 _sqltexter.GetViewList(); // 生成获取指定数据库的View列表的SQL语句 _sqltexter.GetViewList("database"); // 生成删除当前数据库的View的SQL语句 _sqltexter.DeleteView("view01"); // 生成删除指定数据库的View的SQL语句 _sqltexter.DeleteView("database","view01");生成函数(Function)相关的SQL语句
// 生成获取当前数据库的指定函数信息的SQL语句 _sqltexter.GetFunction("func01"); // 生成获取指定数据库的指定函数信息的SQL语句 _sqltexter.GetFunction("database","func01"); // 生成获取当前数据库的函数列表的SQL语句 _sqltexter.GetFunctionList(); // 生成获取指定数据库的函数列表的SQL语句 _sqltexter.GetFunctionList("database"); // 生成删除当前数据库的Function的SQL语句 _sqltexter.DeleteFunction("func01"); // 生成删除指定数据库指定函数的SQL语句 _sqltexter.DeleteFunction("database","func01");生成存储过程(Procedure)相关的SQL语句
// 生成获取当前数据库的指定存储过程信息的SQL语句 _sqltexter.GetProcedure("proc01"); // 生成获取指定数据库的指定存储过程信息的SQL语句 _sqltexter.GetProcedure("database","proc01"); // 生成获取当前数据库的存储过程列表的SQL语句 _sqltexter.GetProcedureList(); // 生成获取指定数据库的存储过程列表的SQL语句 _sqltexter.GetProcedureList("database"); // 生成删除当前数据库的Procedure的SQL语句 _sqltexter.DeleteProcedure("proc01"); // 生成删除指定数据库指定存储过程的SQL语句 _sqltexter.DeleteProcedure("database","proc01");
4.4 扩展使用
1)ToEntity1st(查询数据,并将首条数据转换为数据实例)
// ToEntity1st(查询数据,并将首条数据转换为数据实例)
using JCoder.Db4Net;
using JCoder.Db4Net;
IDbOperator _operator = new MsSqlFactoryOperator()
{
ConnectionString = "Server=127.0.0.1;Database=test;Uid = user; Pwd=testpassword;"
};
return _operator.ToEntity1st<T>("select top 1 * from table1;");
2)ToEntities(查询数据,并转换为数据实体列表)
// ToEntities(查询数据,并转换为数据实体列表)
using JCoder.Db4Net;
IDbOperator _operator = new MsSqlFactoryOperator()
{
ConnectionString = "Server=127.0.0.1;Database=test;Uid = user; Pwd=testpassword;"
};
return _operator.ToEntities<T>("select top 10 * from table1;");
3)CRUD(增删查改)
using JCoder.Db4Net;
// Test Entity Class
[DbTable("t_table_test")]
public class TestEntity
{
[DbPrimaryKey]
[DbAutoIncrement]
public int Key001 { get; set; }
[DbPrimaryKey]
[DbField(IsUnique=true)]
public string Key002 { get; set; }
[DbIndex("idx01")]
public string C003 { get; set; }
}
IDbOperator _operator = new MsSqlFactoryOperator()
{
ConnectionString = "Server=127.0.0.1;Database=test;Uid = user; Pwd=testpassword;"
};
TestEntity x = new TestEntity()
{
Key001 = 101,
Key002 = "Test PK",
};
// Insert Data(新增数据)
_operator.Insert<TestEntity>(x);
// Update Data(更新数据)
x.C003 = "Update Test";
_operator.Update<TestEntity>(x);
// Delete Data(删除数据)
_operator.Delete<TestEntity>(x);
// Select Data(查询数据)
_operator.Select1st<TestEntity>(" and Key001=101 and Key002='Test PK'");
4)Create\Drop Table From Entity(由实体类创建\删除数据库的数据表)
using JCoder.Db4Net;
// Test Entity Class
[DbTable("t_table_test")]
public class TestEntity
{
[DbPrimaryKey]
[DbAutoIncrement]
public int Key001 { get; set; }
[DbPrimaryKey]
[DbField(IsUnique =true)]
public string Key002 { get; set; }
[DbIgnore]
public string Key003 { get; set; }
[DbIndex]
[DbField(Default = "", Description = "Test Comment")]
public string C001 { get; set; }
[DbIndex("idx01")]
public string C002 { get; set; }
[DbIndex("idx01")]
public string C003 { get; set; }
[DbIgnore]
public int C004 { get; set; }
[DbField(Default = "0", Description = "Test Comment2")]
public int C005 { get; set; }
[DbNumberExt(Precision = 11, Scale = 2)]
public double C006 { get; set; }
[DbField(Default = "", Description = "Test Comment2")]
public string C007 { get; set; }
public string C008 { get; set; }
[DbTimeExt(UpdateTimeOnCreate = true, UpdateTimeOnUpdate = true)]
public DateTime C009 { get; set; }
}
IDbOperator _operator = new MsSqlFactoryOperator()
{
ConnectionString = "Server=127.0.0.1;Database=test;Uid = user; Pwd=testpassword;"
};
_operator.CreateTable<TestEntity>();
_operator.DropTable<TestEntity>();
3.5 Db工具类使用
1)转换首条数据为实体对象(支持DbDataReader、DataTable)
using JCoder.Db4Net;
// data source
var _table = new DataTable();
// Property only.
var _result = JCoder.Db4Net.Db.ToObject1st<T>(_table);
var _result = _table.ToObject1st<T>();
// Attributes first
var _result = JCoder.Db4Net.Db.ToEntity1st<T>(_table);
var _result = _table.ToEntity1st<T>();
2)将数据转换为实体对象(支持DataRow、IDictionary<string, string>、IDictionary<string, object>))
using JCoder.Db4Net;
// data source
var _dict = new Dictionary<string, string>();
// Attributes first
var _result = JCoder.Db4Net.Db.ToEntities<T>(_dict);
var _result = _dict.ToEntities<T>();
// Property only.
var _result = JCoder.Db4Net.Db.ToObject<T>(_dict);
var _result = _dict.ToObject<T>();
3)将数据源转换为实体对象列表(支持DbDataReader、DataTable)
using JCoder.Db4Net;
// data source
var _table = new DataTable();
// Attributes first
var _result = JCoder.Db4Net.Db.ToEntities<T>(_table);
var _result = _table.ToEntities<T>();
// Property only.
var _result = JCoder.Db4Net.Db.ToObjects<T>(_table);
var _result = _table.ToObjects<T>();
4)将数据源转换为实体对象字典(支持DbDataReader、DataTable)
using JCoder.Db4Net;
// data source
var _table = new DataTable();
_table.Columns.Add(new DataColumn("ID", typeof(string)));
// Property only.
var _result = JCoder.Db4Net.Db.ToObjectDictionary<T>(_table, "ID");
var _result = _table.ToObjectDictionary<T>("ID");
// Attributes first
var _result = JCoder.Db4Net.Db.ToEntityDictionary<T>(_table, "ID");
var _result = _table.ToEntityDictionary<T>("ID");
5)将数据填充到已有的实体对象里(支持DbDataReader、DataRow、IDictionary<string, string>、IDictionary<string, object>)
using JCoder.Db4Net;
var _target = new T();
// data source
var _source = new DbDataReader();
// Property only.
var _result = JCoder.Db4Net.Db.FillInObject<T>(_source, _target);
var _result = _source.FillInObject<T>(_target);
// Attributes first
var _result = JCoder.Db4Net.Db.FillInEntity<T>(_source, _target);
var _result = _source.FillInEntity<T>(_target);
6)将实体对象转换为DataTable
using JCoder.Db4Net;
var _list = new List<T>();
var t = new T();
// Property only.
// 实体对象转换为DataTable
DataTable _table = JCoder.Db4Net.Db.ObjectToDataTable(t);
DataTable _table = t.ObjectToDataTable();
// 实体对象列表转换为DataTable
DataTable _table = JCoder.Db4Net.Db.ObjectsToDataTable(_list);
DataTable _table = _list.ObjectsToDataTable();
// Attributes first
// 实体对象转换为DataTable
DataTable _table = JCoder.Db4Net.Db.EntityToDataTable(t);
DataTable _table = t.EntityToDataTable();
// 实体对象列表转换为DataTable
DataTable _table = JCoder.Db4Net.Db.EntitiesToDataTable(_list);
DataTable _table = _list.EntitiesToDataTable();
7)将List转换为DataTable
using JCoder.Db4Net;
// 将List转换为DataTable(使用特性进行排序,自定义名称等)
public class BoTest
{
[DbSubField("Width", "S001-Width", Sort = 2120)]//获取Size对象里的Width属性值,并显示为"S001-Width"
[DbSubField("Height", "S001-Height", Sort = 2121)]//获取Size对象里的Height属性值,并显示为"S001-Height"
public Size S001 { get; set; }
public string Key { get; set; }
[DbEnumName]//枚举显示为文本
public AttributeTargets AT { get; set; }
public AttributeTargets AT2 { get; set; }
[DbSort(100)]
public string P100 { get; set; }
[DbSort(111)]//设置排序值(从小到大依次排序)
public string P111 { get; set; }
public DateTime CreateTime { get; set; }
[DbIgnoreConvertion]//转换时忽略
public int Z001 { get; set; }
}
var _list = new List<BoTest>();
for (int i = 0; i < 100; i++)
{
_list.Add(new()
{
S001 = new(i * 100, i * 1000),
Key = $"Key_{i}",
P100 = $"P100_{i}",
P111 = $"P111_{i}",
CreateTime = DateTime.Now,
Z001 = i,
AT = AttributeTargets.Interface,
AT2 = AttributeTargets.Delegate,
});
}
var _table = JCoder.Db4Net.Db.EntitiesToDataTable(_list);
8)将实体对象转换为Dictionary<string,string>
using JCoder.Db4Net;
var t = new T();
// Property only.
// 实体对象转换为Dictionary<string,string>
Dictionary<string, string> _dict = JCoder.Db4Net.Db.ObjectToDict(t);
Dictionary<string, string> _dict = t.ObjectToDict();
// Attributes first
// 实体对象转换为Dictionary<string,string>
Dictionary<string, string> _dict = JCoder.Db4Net.Db.EntityToDict(t);
Dictionary<string, string> _dict = t.EntityToDict();
3.6 类Linq方式
1) Query查询数据
using JCoder.Db4Net;
IDbOperator _dber = Db.Hub.GetDberOrNew<MySqlFactoryOperator>();
var _exper = _dber.NewQuery<BoTest001>();
_exper.UseParameter(true); // 是否使用参数化执行Sql(Using sql parameters for sql execution).
_exper.Where(x => x.Key=="ABC"); // 设置筛选条件,Key="ABC"
_exper.Where(x => x.Key=="ABC" || x.Int001 > 5); // 设置筛选条件,Key="ABC" 或者 Int001>5
_exper.Where(x => x.Key=="ABC" && x.Int001 > 5); // 设置筛选条件,Key="ABC" 并且 Int001>5
_exper.Where(x => x.Key=="ABC")
.Where(x => x.Int001 > 5); // 设置筛选条件,Key="ABC" 并且 Int001>5
_exper.OrderBy(x => x.Key); // 设置排序,以Key排序
_exper.OrderByDesc(x => x.Key); // 设置排序,以Key倒序
_exper.OrderBy(x => x.Bool001)
.OrderByDesc(x => x.Key); // 设置排序,Bool001为第一排序,Key为第二排序(倒序)
_exper.Limited(5); // 设置只获取前5条数据
_exper.Limited(20,5); // 设置获取从第20条起的5条数据
_exper.Paging(5,10); // 设置获取第5页数据(10条数据为1页,起始页码为1)
_exper.Select(x => x.AT); // 设置只查询AT数据列
_exper.Select("Column001", x => x.CreateTime); // 设置只查询CreateTime数据列,并为之重命名为Column001
// 执行SQL并返回结果
ExecResult<DataTable> _result = _exper.RunToTableR();
DataTable _result = _exper.RunToTable();
List<BoTest001> _result = _exper.RunToList<BoTest001>();
BoTest001 _result = _exper.RunTo1st<BoTest001>();
ExecResult<bool> _result = _exper.RunToExistR();
bool _result = _exper.RunToExist();
2) Delete删除数据
using JCoder.Db4Net;
IDbOperator _dber = Db.Hub.GetDberOrNew<MySqlFactoryOperator>();
var _exper = _dber.NewDelete<BoTest001>();
_exper.UseParameter(true); // 是否使用参数化执行Sql(Using sql parameters for sql execution).
_exper.Where(x => x.Key=="ABC"); // 设置筛选条件,Key="ABC"
_exper.Where(x => x.Key=="ABC" || x.Int001 > 5); // 设置筛选条件,Key="ABC" 或者 Int001>5
_exper.Where(x => x.Key=="ABC" && x.Int001 > 5); // 设置筛选条件,Key="ABC" 并且 Int001>5
_exper.Where(x => x.Key=="ABC")
.Where(x => x.Int001 > 5); // 设置筛选条件,Key="ABC" 并且 Int001>5
_exper.OrderBy(x => x.Key); // 设置排序,以Key排序
_exper.OrderByDesc(x => x.Key); // 设置排序,以Key倒序
_exper.OrderBy(x => x.Bool001)
.OrderByDesc(x => x.Key); // 设置排序,Bool001为第一排序,Key为第二排序(倒序)
_exper.Limited(5); // 设置只删除前5条数据
// 执行SQL并返回结果
ExecResult<int> _result = _exper.RunR();
int _result = _exper.Run();
3) Update更新数据
using JCoder.Db4Net;
IDbOperator _dber = Db.Hub.GetDberOrNew<MySqlFactoryOperator>();
var _exper = _dber.NewUpdate<BoTest001>();
_exper.UseParameter(true); // 是否使用参数化执行Sql(Using sql parameters for sql execution).
_exper.Where(x => x.Key=="ABC"); // 设置筛选条件,Key="ABC"
_exper.Where(x => x.Key=="ABC" || x.Int001 > 5); // 设置筛选条件,Key="ABC" 或者 Int001>5
_exper.Where(x => x.Key=="ABC" && x.Int001 > 5); // 设置筛选条件,Key="ABC" 并且 Int001>5
_exper.Where(x => x.Key=="ABC")
.Where(x => x.Int001 > 5); // 设置筛选条件,Key="ABC" 并且 Int001>5
_exper.OrderBy(x => x.Key); // 设置排序,以Key排序
_exper.OrderByDesc(x => x.Key); // 设置排序,以Key倒序
_exper.OrderBy(x => x.Bool001)
.OrderByDesc(x => x.Key); // 设置排序,Bool001为第一排序,Key为第二排序(倒序)
_exper.Limited(5); // 设置只删除前5条数据
_exper.Update(x => x.Key=="ABC"); // 更新数据列Key的值为ABC
_exper.Update(x => x.Key=="ABC" && x.Int001 == 5); // 更新数据列Key的值为ABC,数据列Int001的值为5
_exper.Update(x => x.CreateTime, DateTime.Now); // 更新数据列CreateTime的值为当前时间
// 执行SQL并返回结果
ExecResult<int> _result = _exper.RunR();
int _result = _exper.Run();
3.7 Linq查询(DbQueryable<T>)
说明:3.6 为基于
DbSelectExpresser的"类Linq方式"(NewQuery创建),本节为基于DbQueryable<T>的完整 Linq 查询。两种方式都实现同一查询表达器契约IDbQueryExpresser(见 3.8),可按需选用;DbQueryable<T>更贴近 System.Linq 习惯,且可同时作为IQueryable<T>使用标准 Linq 扩展。
1) 获取查询(From<TEntity>)
using JCoder.Db4Net;
using JCoder.Db4Net.MySql; // 按数据库方言引用(MySql/Sqlite/SqlServer)
IDbOperator _dber = Db.Hub.GetDberOrNew<MySqlFactoryOperator>();
// From<TEntity>() 创建 DbQueryable<TEntity>,即查询起点
var _query = _dber.From<BoTest001>();
2) 链式查询
using JCoder.Db4Net;
var _query = _dber.From<BoTest001>();
// Where:筛选条件(支持 ==/!=/</>/<=/>=、&&/||、字符串 Contains/StartsWith/EndsWith、Contains(集合) 转 IN 等)
_query.Where(x => x.Key == "ABC"); // Key = 'ABC'
_query.Where(x => x.Key == "ABC" || x.Int001 > 5); // 或者
_query.Where(x => x.Key == "ABC" && x.Int001 > 5); // 并且
_query.Where(x => x.Key == "ABC").Where(x => x.Int001 > 5); // 链式累加条件
// OrderBy / OrderByDescending / ThenBy / ThenByDescending:排序
_query.OrderBy(x => x.Key); // 升序
_query.OrderByDescending(x => x.Key); // 降序
_query.OrderBy(x => x.Bool001).ThenByDescending(x => x.Key); // 第一排序 + 第二排序
// Select:列投影(单列 / 匿名类型)
_query.Select(x => x.Int001); // 只查 Int001 列
_query.Select(x => new { x.Key, x.Int001 }); // 匿名投影(生成对应查询列)
// GroupBy + Having:分组与分组过滤(配合聚合)
_query.GroupBy(x => x.Int001); // 按 Int001 分组
_query.GroupBy(x => x.Int001).Having(x => x.Int001 > 0); // 分组后过滤(HAVING)
// Skip / Take / Distinct / Reverse:分页与去重
_query.Skip(5); // 跳过前 5 条
_query.Take(10); // 只取 10 条
_query.Distinct(); // 去重
_query.Reverse(); // 反序
// Union / Concat / Except / Intersect:集合运算(与另一查询合并)
_query.Union(_dber.From<BoTest001>().Where(x => x.Int001 > 5));
// SelectMany:集合展开
_query.SelectMany(x => _dber.From<BoTest001>().Where(y => y.Key == x.Key));
3) Join / GroupJoin
using JCoder.Db4Net;
var _items = _dber.From<BoTest001>();
var _tags = _dber.From<BoTest002>();
// Join:内连接
var _join = _items.Join(_tags,
a => a.Key, // 主表连接键
b => b.Key, // 副表连接键
(a, b) => new { a.Key, b.Int001 }); // 结果投影
// GroupJoin:左连接分组(副表无匹配时为空集合,主表行保留)
var _groupJoin = _items.GroupJoin(_tags,
a => a.Key,
b => b.Key,
(a, g) => new { a.Key, C = g.Count() }); // 每组数量
// 说明:GroupJoin 物化为 LEFT JOIN;GroupJoin 之后的 Select/Where/OrderBy 等
// 在内存中续接(不生成 SQL),直接 ToList()/To1st() 等物化执行。
var _rows = _groupJoin.Where(x => x.C > 0).ToList();
4) 分页(Paging)
using JCoder.Db4Net;
// 方式一:链上 Paging(页码, 每页数量),配合 IDbQueryExpresser 的 RunToPaging* 执行
var _page = _dber.From<BoTest001>()
.OrderBy(x => x.Key)
.Paging(2, 10); // 第 2 页,每页 10 条(页码从 1 开始)
PagingReturn<List<BoTest001>> _page1 = _page.RunToPagingListT<BoTest001>(); // 分页实体
PagingReturn<List<int>> _page2 = _dber.From<BoTest001>()
.Select(x => x.Int001).OrderBy(x => x) // 投影为标量后按值本身排序
.Paging(2, 10)
.RunToPagingValues<int>(); // 分页首列值
// _page.Pagination.Qty 为总数、PageTotal 为总页数;Data 为当前页数据
// 方式二:终端 ToPagingList(页码, 每页数量)(终端参数优先,链上未设 Paging 时使用)
var _page3 = _dber.From<BoTest001>().OrderBy(x => x.Key).ToPagingList(2, 10);
5) 聚合与存在判断
using JCoder.Db4Net;
using System.Linq; // 标准 Linq 扩展(IQueryable<T> 路径)
var _query = _dber.From<BoTest001>();
// 库内终端方法
int _count = _query.ToCount(); // 总条数(COUNT)
bool _any = _query.ToAny(); // 是否存在数据
int _max = _query.Select(x => x.Int001).ToScalar<int>(); // 首行首列标量
// 直接使用 System.Linq 聚合(DbQueryable<T> 同时实现 IQueryable<T>)
IQueryable<BoTest001> _iq = _dber.From<BoTest001>();
int _c1 = _iq.Count(); // 总条数
int _c2 = _iq.Count(x => x.Int001 > 5); // 带谓词的条数
bool _any2 = _iq.Any(x => x.Int001 > 5); // 带谓词的存在判断
int _sum = _iq.Sum(x => x.Int001); // 求和
int _max2 = _iq.Max(x => x.Int001); // 最大值
int _min2 = _iq.Min(x => x.Int001); // 最小值
double _avg = _iq.Average(x => x.Int001); // 平均值
6) 执行与物化(终端方法)
using JCoder.Db4Net;
var _query = _dber.From<BoTest001>().Where(x => x.Int001 > 5).OrderBy(x => x.Key);
List<BoTest001> _list = _query.ToList(); // 实体列表
BoTest001[] _array = _query.ToArray(); // 实体数组
BoTest001 _first = _query.To1st(); // 首个实体
BoTest001? _firstOrNull = _query.To1stOrDefault(); // 首个实体(无数据时为 null)
// 首行首列标量、条数、存在判断
int _scalar = _query.Select(x => x.Int001).ToScalar<int>();
int _count = _query.ToCount();
bool _any = _query.ToAny();
// 生成 SQL(不执行)
string _sql = _query.ToSQL(); // 生成 SELECT SQL
DbExecuteArgument _arg = _query.ToExecuteArgument(); // SQL + 参数
7) 直接使用 System.Linq(接口路径与查询语法)
using JCoder.Db4Net;
using System.Linq;
// DbQueryable<T> 实现 IQueryable<T>,标准 Queryable 扩展可直接使用
IQueryable<BoTest001> _query = _dber.From<BoTest001>();
var _rows = _query.Where(x => x.Int001 > 5)
.OrderBy(x => x.Key)
.Select(x => new { x.Key, x.Int001 })
.ToList();
// 查询语法(C# 编译为 Queryable 调用树,同样被翻译为 SQL)
var _rows2 = (from x in _dber.From<BoTest001>()
where x.Int001 > 5
orderby x.Key
select x).ToList();
// 两表 Join 查询语法
var _rows3 = (from a in _dber.From<BoTest001>()
join b in _dber.From<BoTest002>() on a.Key equals b.Key
select new { a.Key, b.Int001 }).ToList();
8) 参数模式(UseParameter)
using JCoder.Db4Net;
// 默认内联生成 SQL(值直接写入 SQL);UseParameter(true) 改为参数化执行
var _query = _dber.From<BoTest001>()
.Where(x => x.Key == "ABC")
.UseParameter(true);
string _sql = _query.ToSQL(); // 形如 select * from t_test001 where Key=@P0;
DbExecuteArgument _arg = _query.ToExecuteArgument(); // SQL + 参数值列表
说明:所有包含表达式的函数,表达式无法正确解析为 SQL 时都会抛出
DbExpressionParseException,请改写表达式(例如 GroupJoin 之后的链式续接只能在内存中执行,不支持再生成 SQL)。
3.8 Expresser(表达器)统一契约
JCoder.Db4Net 的增删查改都基于"表达器(Expresser)":表达式对象保存操作条件,ToSQL() 生成 SQL,执行方法下发数据库。
| 名称 | 契约 | 用途 |
|---|---|---|
| IDbExpresser | 基契约 | Dber、Reset、UseParameter、ToExecuteArgument、ToSQL |
| IDbQueryExpresser | 查询契约 | 继承 IDbExpresser;RunTo* 全套执行、QueryDictionary、RunRowAsDictionary |
| IDbSelectExpresser<TEntity> | 查询契约 | 查询表达器(Select 相关) |
| IDbDeleteExpresser<TEntity> | 删除契约 | 删除表达器(Delete 相关) |
| IDbUpdateExpresser<TEntity> | 更新契约 | 更新表达器(Update 相关) |
| DbSelectExpresser<TEntity> | 查询实现 | NewQuery 创建,基于表达式构建查询 |
| DbQueryable<TElement> | 查询实现 | From<TEntity> 创建,类 Linq 查询对象 |
1) 获取表达器
using JCoder.Db4Net;
IDbOperator _dber = Db.Hub.GetDberOrNew<MySqlFactoryOperator>();
// 查询:DbSelectExpresser(NewQuery 创建)
IDbSelectExpresser<BoTest001> _select = _dber.NewQuery<BoTest001>();
// 查询:DbQueryable(From 创建,3.7 详述)
IDbQueryExpresser _query = _dber.From<BoTest001>();
// 删除 / 更新
IDbDeleteExpresser<BoTest001> _delete = _dber.NewDelete<BoTest001>();
IDbUpdateExpresser<BoTest001> _update = _dber.NewUpdate<BoTest001>();
2) 统一契约(IDbQueryExpresser)
DbSelectExpresser 与 DbQueryable 实现同一 IDbQueryExpresser,可用同一套方法生成与执行 SQL:
using JCoder.Db4Net;
// 两种查询表达器,同一契约
IDbQueryExpresser _a = new MySqler().From<BoTest001>().Where(x => x.Int001 > 30);
IDbQueryExpresser _b = new DbSelectExpresser<BoTest001>(new MySqler()).Where(x => x.Int001 > 30);
// 两者生成的 SQL 完全一致
string _sqlA = _a.ToSQL();
string _sqlB = _b.ToSQL();
// 契约成员一览(DbQueryable / DbSelectExpresser 都可用)
IDbQueryExpresser _query = _dber.From<BoTest001>().Where(x => x.Int001 > 30).UseParameter(true);
string _sql = _query.ToSQL(); // 生成 SELECT SQL
DbExecuteArgument _arg = _query.ToExecuteArgument(); // SQL + 参数
ExecResult<DataTable> _r = _query.RunToTableR(); // 数据表(带结果包装)
DataTable _table = _query.RunToTable(); // 数据表
bool _exist = _query.RunToExist(); // 是否存在数据
ExecResult<bool> _existR = _query.RunToExistR(); // 是否存在(带结果包装)
int _count = _query.RunToCount(); // 条数
ExecResult<int> _countR = _query.RunToCountR(); // 条数(带结果包装)
List<BoTest001> _list = _query.RunToList<BoTest001>(); // 实体列表
BoTest001 _first = _query.RunTo1st<BoTest001>(); // 首个实体
int _scalar = _query.Select(x => x.Int001).RunToValue<int>(); // 首行首列标量
List<int> _values = _query.Select(x => x.Int001).RunToValues<int>(); // 首列列表
Dictionary<string, string> _dict = _query.Select(x => new { x.Key, x.Int001 }).QueryDictionary<string, string>(); // 首两列转字典
Dictionary<string, string> _row = _query.Select(x => new { x.Key, x.Int001 }).RunRowAsDictionary(); // 首行转字典
注意:
DbSelectExpresser的Select支持单列与成员投影;DbQueryable的Select支持匿名类型投影。两套表达器的执行方法语义一致(参数模式自动带参执行、内联模式直连执行)。
实例使用
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| .NET Framework | net472 is compatible. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.7.2
- JCoder (>= 3.2631.1)
- JCoder.Data (>= 3.2603.1)
-
.NETStandard 2.1
- JCoder (>= 3.2631.1)
- JCoder.Data (>= 3.2603.1)
-
net10.0
- JCoder (>= 3.2631.1)
- JCoder.Data (>= 3.2603.1)
-
net6.0
- JCoder (>= 3.2631.1)
- JCoder.Data (>= 3.2603.1)
-
net8.0
- JCoder (>= 3.2631.1)
- JCoder.Data (>= 3.2603.1)
NuGet packages (8)
Showing the top 5 NuGet packages that depend on JCoder.Db4Net:
| Package | Downloads |
|---|---|
|
JCoder.Db4Net.Sqlite
A library based on JCoder.Db4Net and it support Sqlite. (一个基于JCoder.Db4Net且支持Sqlite的库) |
|
|
JCoder.Db4Net.MySql
A library based on JCoder.Db4Net and it support Mysql.(一个基于JCoder.Db4Net且支持Mysql的库) |
|
|
JCoder.Db4Net.SqlServer
A library based on JCoder.Db4Net and it support microsoft sql server. (一个基于JCoder.Db4Net且支持sql server的库) |
|
|
JCoder.Extension.SqliteAssistKitsts
一款使用Sqlite进行辅助的工具库。 |
|
|
JCoder.Log4Net.Sqlite
A simple log message library by sqlite and it base on JCoder.Log4Net.(一款基于JCoder.Log4Net的用Sqlite记录信息的简易类库) |
GitHub repositories
This package is not used by any popular GitHub repositories.
Please contact Jackie by QQ 1378071853 or E-mail JackieLaw-dev@outlook.com;