NewLife.XCode是一个有15年历史的开源数据中间件,支持netcore/net45/net40,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode。
整个系列教程会大量结合示例代码和运行日志来进行深入分析,蕴含多年开发经验于其中,代表作有百亿级大数据实时计算项目。
开源地址:https://github.com/NewLifeX/X (求star, 620+)
增删改查入门
新建控制台项目(.NET Core),从nuget引用NewLife.XCode,(也可以从别的项目引用下载后拷贝XCode.dll和NewLife.Core.dll来使用,区分nfx和netcore版本),敲入以下代码
// 启用控制台日志 XTrace.UseConsole(); // 添加 var user = new User { Name = "大石头", Enable = true }; user.Insert(); // 自增字段user.ID已经取得值 XTrace.WriteLine("用户ID:{0}", user.ID); // 查询 var user2 = User.Find(User._.Name == "大石头"); // 更新 user2.Logins++; user2.LastLogin = DateTime.Now; user2.Update(); // 删除 var user3 = User.FindByID(user.ID); user3.Delete(); Console.ReadLine();
先跑起来看看效果:
#Software: ConsoleApp4 #ProcessID: 21252 x64 #AppDomain: ConsoleApp4 #FileName: C:\Program Files\dotnet\dotnet.exe #BaseDirectory: D:\Test\ConsoleApp4\ConsoleApp4\bin\Debug\netcoreapp2.1 #CommandLine: D:\Test\ConsoleApp4\ConsoleApp4\bin\Debug\netcoreapp2.1\ConsoleApp4.dll #ApplicationType: Console #CLR: 4.0.30319.42000, #OS: Microsoft Windows NT 6.2.9200.0, X3/Stone #CPU: 8 #GC: IsServerGC=False, LatencyMode=Interactive #Date: 2019-02-25 #字段: 时间 线程ID 线程池Y网页W普通N 线程名 消息内容 #Fields: Time ThreadID IsPoolThread ThreadName Message 22:57:13.089 1 N - NewLife.Core v8.0.2019.0101 Build 2019-01-26 23:22:36 22:57:13.104 1 N - 新生命X组件核心库 ©2002-2019 新生命开发团队 22:57:13.114 1 N - ConsoleApp4 v1.0.0.0 Build 2000-01-01 22:57:13.115 1 N - ConsoleApp4 22:57:13.115 1 N - Setting的配置文件Config\Core.config 不存在,准备用默认配置覆盖! 22:57:13.277 1 N - Setting的配置文件Config\XCode.config 不存在,准备用默认配置覆盖! 22:57:13.282 1 N - XCode v9.10.2019.0101 Build 2019-01-26 23:22:38 22:57:13.282 1 N - 数据中间件 ©2002-2019 新生命开发团队 22:57:13.628 1 N - 自动为[Membership]设置SQLite连接字符串:Data Source=.\Membership.db;Migration=On 22:57:13.652 1 N - System.Data.SQLite.dll不存在或平台版本不正确,准备联网获取 http://x.newlifex.com/ 22:57:13.835 1 N - 下载链接 http://x.newlifex.com/,目标 System.Data.SQLite.win-x64,System.Data.SQLite.win,System.Data.SQLite.st,System.Data.SQLite 22:57:13.964 4 Y 1 WebClientX.Get http://x.newlifex.com/ 22:57:15.660 1 N - 分析得到文件 System.Data.SQLite.win-x64_20180823112512.zip,准备下载 http://x.newlifex.com/System.Data.SQLite.win-x64_20180823112512.zip 22:57:15.663 4 Y 19 WebClientX.Get http://x.newlifex.com/System.Data.SQLite.win-x64_20180823112512.zip 22:57:16.897 1 N - 下载完成,共924,475字节,耗时1,232毫秒 22:57:16.897 1 N - 解压缩到 D:\Test\ConsoleApp4\ConsoleApp4\bin\Debug\netcoreapp2.1\Plugins 22:57:17.074 1 N - TypeX.GetType("System.Data.SQLite.SQLiteFactory") => Plugins\System.Data.SQLite.dll 22:57:17.074 1 N - System.Data.SQLite驱动D:\Test\ConsoleApp4\ConsoleApp4\bin\Debug\netcoreapp2.1\Plugins\System.Data.SQLite.dll 版本v1.0.109.0 22:57:17.145 1 N - Data Source=D:\Test\ConsoleApp4\ConsoleApp4\bin\Debug\netcoreapp2.1\Membership.db;Cache Size=-524288;Synchronous=Off;Journal Mode=WAL 22:57:17.154 4 Y 198 检查实体XCode.Membership.User的数据表架构,模式:CheckTableWhenFirstUse 22:57:17.160 4 Y 198 创建数据库:Membership 22:57:17.161 4 Y 198 创建数据库:D:\Test\ConsoleApp4\ConsoleApp4\bin\Debug\netcoreapp2.1\Membership.db 22:57:17.181 4 Y 198 select * from sqlite_master 22:57:17.284 4 Y 198 创建表:User(用户) 22:57:17.298 4 Y 198 Create Table User( ID integer Primary Key AUTOINCREMENT, Name nvarchar(50) NOT NULL COLLATE NOCASE, Password nvarchar(50) NULL COLLATE NOCASE, DisplayName nvarchar(50) NULL COLLATE NOCASE, Sex int NOT NULL, Mail nvarchar(50) NULL COLLATE NOCASE, Mobile nvarchar(50) NULL COLLATE NOCASE, Code nvarchar(50) NULL COLLATE NOCASE, Avatar nvarchar(200) NULL COLLATE NOCASE, RoleID int NOT NULL, RoleIDs nvarchar(200) NULL COLLATE NOCASE, DepartmentID int NOT NULL, Online bit NOT NULL, Enab...etime NULL, LastLoginIP nvarchar(50) NULL COLLATE NOCASE, RegisterTime datetime NULL, RegisterIP nvarchar(50) NULL COLLATE NOCASE, Ex1 int NOT NULL, Ex2 int NOT NULL, Ex3 real NOT NULL, Ex4 nvarchar(50) NULL COLLATE NOCASE, Ex5 nvarchar(50) NULL COLLATE NOCASE, Ex6 nvarchar(50) NULL COLLATE NOCASE, UpdateUser nvarchar(50) NULL COLLATE NOCASE, UpdateUserID int NOT NULL, UpdateIP nvarchar(50) NULL COLLATE NOCASE, UpdateTime datetime NULL, Remark nvarchar(200) NULL COLLATE NOCASE ) 22:57:17.309 4 Y 198 Create Unique Index IU_User_Name On User (Name) 22:57:17.311 4 Y 198 Create Index IX_User_RoleID On User (RoleID) 22:57:17.312 4 Y 198 Create Index IX_User_UpdateTime On User (UpdateTime) 22:57:17.320 4 Y 198 User.Count 快速计算表记录数(非精确)[User/Membership] 参考值 -2 22:57:17.332 4 Y 198 开始检查连接[Membership/SQLite]的数据库架构…… 22:57:17.355 4 Y 198 [Membership]的所有实体类(5个):Parameter,User,Menu,Role,Department 22:57:17.356 4 Y 198 [Membership]需要检查架构的实体类(1个):Parameter 22:57:17.357 4 Y 198 Membership待检查表架构的实体个数:1 22:57:17.358 4 Y 198 select * from sqlite_master 22:57:17.365 4 Y 198 创建表:Parameter(字典参数) 22:57:17.368 4 Y 198 Create Table Parameter( ID integer Primary Key AUTOINCREMENT, Category nvarchar(50) NULL COLLATE NOCASE, Name nvarchar(50) NULL COLLATE NOCASE, Value nvarchar(200) NULL COLLATE NOCASE, LongValue nvarchar(2000) NULL COLLATE NOCASE, Kind int NOT NULL, Enable bit NOT NULL, Ex1 int NOT NULL, Ex2 int NOT NULL, Ex3 real NOT NULL, Ex4 nvarchar(50) NULL COLLATE NOCASE, Ex5 nvarchar(50) NULL COLLATE NOCASE, Ex6 nvarchar(50) NULL COLLATE NOCASE, CreateUser nvarchar(50) NULL COLLATE NOCASE, CreateUserID int NOT NULL, CreateIP nvarchar(50) NULL COLLATE NOCASE, CreateTime datetime NULL, UpdateUser nvarchar(50) NULL COLLATE NOCASE, UpdateUserID int NOT NULL, UpdateIP nvarchar(50) NULL COLLATE NOCASE, UpdateTime datetime NULL, Remark nvarchar(200) NULL COLLATE NOCASE ) 22:57:17.369 4 Y 198 Create Unique Index IU_Parameter_Category_Name On Parameter (Category, Name) 22:57:17.370 4 Y 198 Create Index IX_Parameter_Name On Parameter (Name) 22:57:17.370 4 Y 198 Create Index IX_Parameter_UpdateTime On Parameter (UpdateTime) 22:57:17.372 4 Y 198 检查连接[Membership/SQLite]的数据库架构耗时38ms 22:57:17.383 4 Y 198 Select * From User Order By ID Desc limit 1 22:57:17.388 4 Y 198 Select Count(*) From User 22:57:17.398 4 Y 198 Select Count(*) From User 22:57:17.401 4 Y 198 开始初始化UserX用户数据…… 22:57:17.455 4 Y 198 Insert Into User(Name, Password, DisplayName, Sex, Mail, Mobile, Code, Avatar, RoleID, RoleIDs, DepartmentID, Online, Enable, Logins, LastLogin, LastLoginIP, RegisterTime, RegisterIP, Ex1, Ex2, Ex3, Ex4, Ex5, Ex6, UpdateUser, UpdateUserID, UpdateIP, UpdateTime, Remark) Values('admin', '21232F297A57A5A743894A0E4A801FC3', '管理员', 0, null, null, null, null, 1, '', 0, 0, 1, 0, null, null, null, null, 0, 0, 0, null, null, null, null, 0, null, null, null);Select last_insert_rowid() newid 22:57:17.479 4 Y 198 自动为[Log]设置SQLite连接字符串:Data Source=.\Log.db;Migration=On 22:57:17.491 4 Y 198 Data Source=D:\Test\ConsoleApp4\ConsoleApp4\bin\Debug\netcoreapp2.1\Log.db;Cache Size=-524288;Synchronous=Off;Journal Mode=WAL 22:57:17.514 4 Y 198 完成初始化UserX用户数据! 22:57:17.548 1 N - Insert Into User(Name, Password, DisplayName, Sex, Mail, Mobile, Code, Avatar, RoleID, RoleIDs, DepartmentID, Online, Enable, Logins, LastLogin, LastLoginIP, RegisterTime, RegisterIP, Ex1, Ex2, Ex3, Ex4, Ex5, Ex6, UpdateUser, UpdateUserID, UpdateIP, UpdateTime, Remark) Values('大石头', null, null, 0, null, null, null, null, 0, null, 0, 0, 1, 0, null, null, null, null, 0, 0, 0, null, null, null, null, 0, null, null, null);Select last_insert_rowid() newid 22:57:17.561 1 N - 用户ID:2 22:57:17.574 1 N - Select * From User Where Name='大石头' Order By ID Desc limit 1 22:57:17.601 1 N - Update User Set Logins=Logins+1, LastLogin='2019-02-25 22:57:17' Where ID=2 22:57:17.613 1 N - Select * From User Order By ID Desc 22:57:17.620 1 N - Delete From User Where ID=2 22:57:18.519 6 Y 199 检查实体XCode.Membership.Log的数据表架构,模式:CheckTableWhenFirstUse 22:57:18.520 6 Y 199 创建数据库:Log 22:57:18.521 6 Y 199 创建数据库:D:\Test\ConsoleApp4\ConsoleApp4\bin\Debug\netcoreapp2.1\Log.db 22:57:18.532 6 Y 199 创建表:Log(日志) 22:57:18.537 4 Y EQ 开始检查连接[Log/SQLite]的数据库架构…… 22:57:18.555 4 Y EQ [Log]的所有实体类(3个):Log,UserOnline,VisitStat 22:57:18.555 4 Y EQ [Log]需要检查架构的实体类(2个):UserOnline,VisitStat 22:57:18.558 4 Y EQ Log待检查表架构的实体个数:2 22:57:18.559 4 Y EQ 创建表:UserOnline(用户在线) 22:57:18.561 4 Y EQ 创建表:VisitStat(访问统计) 22:57:18.564 4 Y EQ 检查连接[Log/SQLite]的数据库架构耗时24ms
这是前述代码的完整执行日志,这里我们不做过多分析。
日志大意是:自动配置SQLite数据库,下载平台要求的SQLite驱动,建库建表,增删改查
这里特别需要关注的是这几行:
22:57:17.548 1 N - Insert Into User(Name, Password, DisplayName, Sex, Mail, Mobile, Code, Avatar, RoleID, RoleIDs, DepartmentID, Online, Enable, Logins, LastLogin, LastLoginIP, RegisterTime, RegisterIP, Ex1, Ex2, Ex3, Ex4, Ex5, Ex6, UpdateUser, UpdateUserID, UpdateIP, UpdateTime, Remark) Values('大石头', null, null, 0, null, null, null, null, 0, null, 0, 0, 1, 0, null, null, null, null, 0, 0, 0, null, null, null, null, 0, null, null, null);Select last_insert_rowid() newid 22:57:17.561 1 N - 用户ID:2 22:57:17.574 1 N - Select * From User Where Name='大石头' Order By ID Desc limit 1 22:57:17.601 1 N - Update User Set Logins=Logins+1, LastLogin='2019-02-25 22:57:17' Where ID=2 22:57:17.613 1 N - Select * From User Order By ID Desc 22:57:17.620 1 N - Delete From User Where ID=2
一句user.Insert,生成了一个Insert Into语句,并取得自增字段赋值给ID。
一个简单的Find单字段查找,通过user2.Update更新了两个字段,user3.Delete则删除了这行数据。
这就是一个完整的增删改查!
短短的一段代码,也许带给你许多疑问,这些疑问都将在后续文章中得到详细解答:
- User类来自哪里?(XCode内置权限体系Membership)
- 为何不需要配置数据库?(无配置时默认使用SQLite)
- 下载了什么东西?(SQLite驱动分为.Net2.0/.Net4.0/.Net4.5等,还有.netstandard以及Linux版本之分,XCode根据平台自动下载正确版本)
- 为何会自动建表?(这是XCode最为强大的反向工程,2008年开始支持,类似于EF后来的数据迁移)
- 自增ID。Insert后会即刻取回新插入的自增值
- Logins=Logins+1。这叫做累加字段
- User.FindByID为何生成不带where的Select查询?(User.FindByID内部带有实体缓存,并非简单的Find(ID==2))
数据访问层DAL
整个XCode明确分隔为上下两层(实体层Entity和数据访问层DAL),前面介绍了实体层添删改查。
由于XCode实体层只支持单表查询,存在不支持多表Join等制约,有时候不得不直接写SQL来解决问题(特别是新手)。
数据层DAL可以执行任意的添删改查SQL语句,包括多表Join等,并支持映射到任意实体模型类。
在前面的示例后续继续加代码,在连接名Membership上执行sql语句:
var dal = DAL.Create("Membership"); var dt = dal.Query("select * from user"); XTrace.WriteLine(dt.ToJson());
跑起来:
21:03:09.947 1 N - 自动为[Membership]设置SQLite连接字符串:Data Source=Data\Membership.db;Migration=On 21:03:09.972 1 N - [System.Data.SQLite.SQLite]驱动 D:\Test\ConsoleApp22\ConsoleApp22\bin\Debug\net7.0\Plugins\System.Data.SQLite.dll 版本v1.0.116.0 21:03:09.991 1 N - [Membership] select * from user 21:03:09.994 1 N - Data Source=D:\Test\ConsoleApp22\ConsoleApp22\bin\Debug\net7.0\Data\Membership.db;Cache Size=-524288;Synchronous=Off;Journal Mode=WAL 21:03:09.995 1 N - [Membership] DataSource=D:\Test\ConsoleApp22\ConsoleApp22\bin\Debug\net7.0\Data\Membership.db Database= User= 21:03:10.032 1 N - [{"ID":1,"Name":"admin","Password":"21232F297A57A5A743894A0E4A801FC3","DisplayName":"管理员","Sex":0,"Mail":null,"Mobile":null,"Code":null,"AreaId":0,"Avatar":null,"RoleID":1,"RoleIds":"","DepartmentID":0,"Online":false,"Enable":true,"Age":0,"Birthday":"","Logins":0,"LastLogin":"","LastLoginIP":null,"RegisterTime":"","RegisterIP":null,"OnlineTime":0,"Ex1":0,"Ex2":0,"Ex3":0,"Ex4":null,"Ex5":null,"Ex6":null,"UpdateUser":"","UpdateUserID":0,"UpdateIP":null,"UpdateTime":"2023-05-16 20:55:17","Remark":null}]
可以看到,代码选择连接名Membership,但是我们并没有给这个连接设置连接字符串。于是XCode自动添加SQLite连接字符串。后面就是执行sql语句并返回结果了。
实体层的所有添删改查操作,本质上都是根据目标连接数据库类型来生成不同的SQL语句,交给数据访问层DAL执行。
显然,可以越过实体层,直接操作数据访问层DAL。
DAL是单例模式,只有一个获取办法 DAL.Create(connName),每个连接名对应一个DAL对象。
(少数同学习惯把连接字符串当作连接名connName传递给DAL.Create)
DAL基本数据操作:
- DataSet Select(sql)。根据指定sql查询得到DataSet,这就是标准的DbHelper必备
- DbTable Query(sql)。根据指定sql查询得到DbTable,这是XCode自定义内存数据表,比DataTable更轻量级,并易于网络传输以及保存二进制文件
- Int32 SelectCount(sql)。满足指定sql的总行数,常用于分页,或者判断指定主键的数据是否存在
- Int32 Execute(sql)。执行添删改查操作,或者执行存储过程
- Int32 InsertAndGetIdentity(sql)。执行插入并取得自增数字
DAL的Mapper数据操作:
- IEnumerable<T> Query<T>(String sql, Object param = null)。执行参数化的sql语句,并通过匿名对象传递参数,支持分页。
- T QuerySingle<T>(String sql, Object param = null)。执行参数化sql,查单行。
- Int32 Execute(String sql, Object param = null)。执行参数化sql,并通过匿名对象传递参数。
- Int32 Insert(Object data, String tableName = null)。插入对象,自动生成insert语句。
- Int32 Update(Object data, Object where, String tableName = null)。更新对象
- Int32 Delete(String tableName, Object where)。删除对象
很多人问过,XCode怎么做多表关联查询?
var dal = DAL.Create("Membership"); var db = dal.Query("select a., b. from user a left join department b on a.departmentid=b.id where a.enable=1"); var list = Member.LoadData(db);
这是一个典型多表Join,可以借助DAL.Query实现查询,然后通过实体类的LoadData方法,把结果集映射为实体列表。
数据结果集DataSet/DbTable理论上可以LoadData映射到任意实体类,只填充实体类中存在的字段,不存在的字段则把数据存放在实体对象的扩展属性Extends中。
什么时候使用数据访问层?
- 需要进行多表Join等复杂查询
- 只需要偶尔查询或写入数据,不想生成实体类
- 方便迁移旧版DbHelper代码
连接字符串
实体类通过BindTable特性的ConnName连接名来指定使用哪一个数据库连接字符串。
XCode内置实体类的连接名是 Membership 和 Log。
继续前面的示例代码,添加配置文件appsettings.json,设置Membership连接字符串为本机Mysql:
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*", "ConnectionStrings": { "Membership": "Server=.;Port=3306;Database=Membership;Uid=root;Pwd=root;provider=mysql", "Log": "Data Source=..\\Data\\Log.db;provider=sqlite" } }
appsettings.json文件属性,设置为“如果较新则复制”以及“内容”。编译一次项目,即可把这个配置文件输出到目标目录。
完整代码:
using NewLife.Log; using XCode.DataAccessLayer; using XCode.Membership; // 启用控制台日志 XTrace.UseConsole(); // 添加 var user = new User { Name = "大石头", Enable = true }; user.Insert(); // 自增字段user.ID已经取得值 XTrace.WriteLine("用户ID:{0}", user.ID); // 查询 var user2 = User.Find(User._.Name == "大石头"); // 更新 user2.Logins++; user2.LastLogin = DateTime.Now; user2.Update(); // 删除 var user3 = User.FindByID(user.ID); user3.Delete(); Console.ReadLine(); // 直接执行SQL var dal = DAL.Create("Membership"); var dt = dal.Query("select * from user"); XTrace.WriteLine(dt.ToJson()); Console.ReadLine();
跑起来的日志:
21:19:33.922 1 N - XCode v11.8.2023.0503 Build 2023-05-03 .NET Standard 2.1 21:19:33.922 1 N - NewLife数据中间件 ?2002-2023 NewLife 21:19:33.922 1 N - 当前配置为输出SQL日志,如果觉得日志过多,可以修改配置关闭[Config/XCode.config:ShowSQL=false]。 21:19:34.287 1 N - MySql.Data.dll不存在或平台版本不正确,准备联网获取 http://x.newlifex.com/ 21:19:34.291 1 N - 下载链接 http://x.newlifex.com/,目标 MySql.Data.win-x64,MySql.Data.win,MySql.Data_net70,MySql.Data_netstandard21,MySql.Data_netstandard20,MySql.Data 21:19:34.297 9 Y P 保存配置 D:\Test\ConsoleApp22\ConsoleApp22\bin\Debug\net7.0\Config\Socket.config 21:19:34.299 9 Y P WebClientX.Get http://x.newlifex.com/ 21:19:34.603 1 N - 分析得到文件 MySql.Data_net70_v8.0.30_20220824.zip,准备下载 http://x.newlifex.com/MySql.Data_net70_v8.0.30_20220824.zip,保存到 D:\Test\ConsoleApp22\ConsoleApp22\bin\Debug\net7.0\Plugins\MySql.Data_net70_v8.0.30_20220824.zip 21:19:34.604 4 Y P WebClientX.Get http://x.newlifex.com/MySql.Data_net70_v8.0.30_20220824.zip 21:19:34.813 1 N - 下载完成,共2,705,580字节,耗时209毫秒 21:19:34.813 1 N - 解压缩到 D:\Test\ConsoleApp22\ConsoleApp22\bin\Debug\net7.0\Plugins 21:19:34.862 1 N - [MySql.Data.MySqlClient.MySql]驱动 D:\Test\ConsoleApp22\ConsoleApp22\bin\Debug\net7.0\Plugins\MySql.Data.dll 版本v8.0.30.0 21:19:34.869 1 N - [Membership] DataSource=127.0.0.1 Database=Membership User=root 21:19:34.960 1 N - [Membership]GetSchema("MetaDataCollections") 21:19:34.971 1 N - [Membership]GetSchema("Databases", "Membership") 21:19:34.974 1 N - [Membership]待检查数据表:User 21:19:35.005 1 N - User.Count 快速计算表记录数(非精确)[User/Membership] 参考值 -2 21:19:35.008 1 N - [Membership] select table_rows from information_schema.tables where table_schema='Membership' and table_name='User' 21:19:35.012 1 N - [Membership] Select Count(*) From `User` 21:19:35.015 1 N - [Membership] Insert Into `User`(Name,Sex,AreaId,RoleID,DepartmentID,Online,Enable,Age,Logins,OnlineTime,Ex1,Ex2,Ex3,UpdateUser,UpdateUserID,UpdateTime) Values('大石头',0,0,3,0,0,1,0,0,0,0,0,0,'',0,'2023-05-16 21:19:34');Select LAST_INSERT_ID() 21:19:35.030 1 N - 用户ID:4 21:19:35.033 1 N - [Membership] Select * From `User` Where Name='大石头' Order By ID Desc limit 1 21:19:35.043 1 N - [Membership] Update `User` Set RoleIds='',Logins=Logins+1,LastLogin='2023-05-16 21:19:35' Where ID=4 21:19:35.053 1 N - [Membership] Select * From `User` 21:19:35.058 1 N - [Membership] Delete From `User` Where ID=4 21:19:36.048 7 Y EQ 创建数据库:D:\Test\ConsoleApp22\ConsoleApp22\bin\Debug\Data\Log.db 21:19:36.052 7 Y EQ [Log]待检查数据表:Log 21:19:36.053 7 Y EQ Microsoft.Data.Sqlite.dll不存在或平台版本不正确,准备联网获取 http://x.newlifex.com/ 21:19:36.054 7 Y EQ 下载链接 http://x.newlifex.com/,目标 Microsoft.Data.Sqlite.win-x64,Microsoft.Data.Sqlite.win,Microsoft.Data.Sqlite_net70,Microsoft.Data.Sqlite_netstandard21,Microsoft.Data.Sqlite_netstandard20 21:19:36.054 14 Y P WebClientX.Get http://x.newlifex.com/ 21:19:36.193 7 Y EQ 未找到 Microsoft.Data.Sqlite.dll 21:19:36.193 7 Y EQ System.Data.SQLite.dll不存在或平台版本不正确,准备联网获取 http://x.newlifex.com/ 21:19:36.193 7 Y EQ 下载链接 http://x.newlifex.com/,目标 System.Data.SQLite.win-x64,System.Data.SQLite.win,System.Data.SQLite_net70,System.Data.SQLite_netstandard21,System.Data.SQLite_netstandard20,System.Data.SQLite 21:19:36.194 14 Y P WebClientX.Get http://x.newlifex.com/ 21:19:36.410 7 Y EQ 分析得到文件 System.Data.SQLite.win-x64_20220621.zip,准备下载 http://x.newlifex.com/System.Data.SQLite.win-x64_20220621.zip,保存到 D:\Test\ConsoleApp22\ConsoleApp22\bin\Debug\net7.0\Plugins\System.Data.SQLite.win-x64_20220621.zip 21:19:36.411 6 Y P WebClientX.Get http://x.newlifex.com/System.Data.SQLite.win-x64_20220621.zip 21:19:36.503 7 Y EQ 下载完成,共1,045,867字节,耗时92毫秒 21:19:36.504 7 Y EQ 解压缩到 D:\Test\ConsoleApp22\ConsoleApp22\bin\Debug\net7.0\Plugins 21:19:36.520 7 Y EQ [System.Data.SQLite.SQLite]驱动 D:\Test\ConsoleApp22\ConsoleApp22\bin\Debug\net7.0\Plugins\System.Data.SQLite.dll 版本v1.0.116.0 21:19:36.538 7 Y EQ Data Source=D:\Test\ConsoleApp22\ConsoleApp22\bin\Debug\Data\Log.db;Cache Size=-524288;Synchronous=Off;Journal Mode=WAL 21:19:36.538 7 Y EQ [Log] DataSource=D:\Test\ConsoleApp22\ConsoleApp22\bin\Debug\Data\Log.db Database= User= 21:19:36.561 7 Y EQ 创建表:Log(日志) 21:19:45.078 10 N T 实体缓存<User>(2) 总次数 1 [XCode.Membership.User]
可以看到,XCode自动下载数据库驱动(也可以Nuget引用MySql.Data),并执行数据库操作。
因此,只要在配置文件里修改Membership后面的连接字符串,XCode就会使用相应的数据库,而代码无需修改!
web.config/app.config
以下是常规.Net Framework 项目(Console/WinForm/WPF/WebForm/ASP.Net MVC)的配置文件。
其中name对应实体类ConnName连接名。
例如,使用User类时,将查找连接名为 Membership 的连接字符串,如果不存在则默认使用SQLite。
<?xml version="1.0" encoding="utf-8"?> <configuration> <connectionStrings> <add name="SQLite" connectionString="Data Source=test.db;" providerName="Sqlite" /> <add name="MySql" connectionString="Server=.;Port=3306;Database=mysql;Uid=root;Pwd=;NameFormat=Upper" providerName="MySql.Data.MySqlClient" /> <add name="MSSQL" connectionString="Server=.;User ID=sa;Password=sa;Database=Test;datapath=~\App_Data;NameFormat=Upper" providerName="System.Data.SqlClient" /> <add name="Oracle" connectionString="Data Source=Tcp://127.0.0.1/ORC;User ID=sys;Password=admin;Owner=mis;NameFormat=Upper" providerName="System.Data.OracleClient" /> <add name="PostgreSQL" connectionString="Server=.;Database=master;Uid=root;Pwd=root;NameFormat=Upper" providerName="PostgreSQL.Data.PostgreSQLClient" /> <add name="MSSQL" connectionString="Server=.;Integrated Security=SSPI;Database=Test;NameFormat=Upper" providerName="System.Data.SqlClient" /> <add name="Oracle" connectionString="Data Source=orc;User ID=sys;Password=admin;NameFormat=Upper" providerName="System.Data.OracleClient" /> <add name="Access" connectionString="Provider=Microsoft.Jet.OLEDB.4.0; Data Source=~\App_Data\Test.mdb;Persist Security Info=False;OLE DB Services=-1;NameFormat=Upper" providerName="Access"/> <add name="SqlCe" connectionString="Data Source=test.sdf;" providerName="SqlCe" /> </connectionStrings> </configuration>
appsettings.json
以下是 .Net Core 项目的配置文件。
其中name对应实体类ConnName连接名。
例如,使用User类时,将查找连接名为 Membership 的连接字符串,如果不存在则默认使用SQLite。
注意,XCode不支持读取带有json注释的appsettings.json文件。
{ "ConnectionStrings": { "SQLite": "Data Source=test.db;provider=Sqlite", "MySql": "Server=.;Port=3306;Database=mysql;Uid=root;Pwd=;provider==mysql", "MSSQL": "Server=.;User ID=sa;Password=sa;Database=Test;datapath=~\\App_Data;provider=SqlClient", "Oracle": "Data Source=Tcp://127.0.0.1/ORC;User ID=sys;Password=admin;Owner=mis;provider=Oracle", "PostgreSQL": "Server=.;Database=master;Uid=root;Pwd=root;provider=PostgreSQL", "MSSQL2": "Server=.;Integrated Security=SSPI;Database=Test;provider=SqlClient", "Oracle2": "Data Source=orc;User ID=sys;Password=admin;provider=Oracle", //OLE DB Services=-1表示打开连接池 "Access": "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=~\\App_Data\\Test.mdb;Persist Security Info=False;OLE DB Services=-1;provider=Access", "SqlCe": "Data Source=test.sdf;provider=SqlCe" } }
连接字符串的更多细节请参考章节