AutoSQL 0.0.1-alpha01

This is a prerelease version of AutoSQL.
dotnet add package AutoSQL --version 0.0.1-alpha01
                    
NuGet\Install-Package AutoSQL -Version 0.0.1-alpha01
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="AutoSQL" Version="0.0.1-alpha01" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="AutoSQL" Version="0.0.1-alpha01" />
                    
Directory.Packages.props
<PackageReference Include="AutoSQL" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add AutoSQL --version 0.0.1-alpha01
                    
#r "nuget: AutoSQL, 0.0.1-alpha01"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package AutoSQL@0.0.1-alpha01
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=AutoSQL&version=0.0.1-alpha01&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=AutoSQL&version=0.0.1-alpha01&prerelease
                    
Install as a Cake Tool

介绍

  • 支持DDD模式、值对象映射。
  • 插入演示数据。
  • 内含日志功能。
  • 内含DTO对象映射功能。
  • 数据库支持:SQL Server、MySQL、SQLite、Access(将添加更多)。
  • 编程语言支持:C#、VB.Net、F#。

开始

安装

命令
.NET CLI dotnet add package DataExpress
Package Manager NuGet\Install-Package DataExpress
PackageReference <PackageReference Include="DataExpress" />
Paket CLI paket add DataExpress

.NET版本支持:

.NET 实现 版本支持
.NET 和.NET Core 2.0、2.1、2.2、3.0、3.1、5.0、6.0、7.0、8.0、9.0
.NET Framework 4.6.1 2、4.6.2、4.7、4.7.1、4.7.2、4.8、4.8.1
Mono 5.4、6.4
Xamarin.iOS 10.14、12.16
Xamarin.Mac 3.8、5.16
Xamarin.Android 8.0、10.0
通用 Windows 平台 10.0.16299,待定
Unity 2018.1

最新版本

API 参考

使用

初始化

初始化DataExpress的对象前,根据使用的数据库引擎驱动程序添加相应的数据提供程序类库及其引用。例如:

using Microsoft.Data.SqlClient; //连接SqlServer数据库。
using Microsoft.Data.Sqlite;    //连接SQLite数据库。
using MySqlConnector;           //连接Mysql数据库。
using System.Data.OleDb;        //连接Access数据库。

提示:Access的数据库引擎程序包,请根据Windows系统选择32位或64位不能混用。

DataExpress有两种主要的类:

  • Database:用来操作数据库,连接字符串中不需要包含数据库名。
    //操作SqlServer数据库。
    Database _sqlserverDatabase = new Database(new SqlConnection("Server=XXX.XXX.XXX.XXX; Uid=XXXX; Pwd=XXXXXXXX; TrustServerCertificate=true"));
    
    //操作Mysql数据库。
    Database _mysqlDatabase = new Database(new MySqlConnection("Server=XXX.XXX.XXX.XXX; Port=XXXX; Uid=XXXX; Pwd=XXXXXXXX; SslMode=Preferred")); 
    
    //操作SQLite数据库。
    Database _sqliteDatabase = new Database(new SqliteConnection());
    
    //操作SQLite数据库。
    Database _accessDatabase = new Database(new OleDbConnection());
    
  • Table:用来操作数据表,连接字符串中需要包含数据库名。
    //操作SqlServer数据表。
    Table _sqlserverTable = new Database(new SqlConnection("Server=XXX.XXX.XXX.XXX; Uid=XXXX; Pwd=XXXXXXXX; Database=XXXX; TrustServerCertificate=true"));
    
    //操作Mysql数据表。
    Table _mysqlTable = new Database(new MySqlConnection("Server=XXX.XXX.XXX.XXX; Port=XXXX; Uid=XXXX; Pwd=XXXXXXXX; Database=XXXX; SslMode=Preferred")); 
    
    //操作SQLite数据表。
    Table _sqliteTable = new Database(new SqliteConnection("Data Source=D:\\XXXX"));
    
    //操作SQLite数据表。
    Table _accessTable = new Database(new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0; Data Source=D:\\XXXX"));
    

IoC注入

对数据库的操作

方法说明

方法 返回值类型 SQL Server MySQL SQLite Access 示例
检查数据库是否存在 Database.IsExist() bool _sqlserverDatabase.IsExist(_db1Name).Execute()
如果存在则删除数据库 Database.DropIfExist() void _sqlserverDatabase.DropIfExist(_db1Name).Execute()
创建数据库 Database.Create() void × _sqlserverDatabase.Create(_db1Name).Execute()
删除数据库 Database.Drop() void _sqlserverDatabase.Drop(_db1Name).Execute()
如果不存在则创建数据库 Database.CreateIfNotExist() void × _sqlserverDatabase.CreateIfNotExist(_db1Name).Execute()
限制和局限
  • Access数据提供程序不支持创建数据库。可使用Access的可视化工具创建数据库。

对数据表的操作

方法说明

方法 返回值类型 SQL Server MySQL SQLite Access 示例
检查数据表是否存在 Table.IsExist<TClass>() bool _sqlserverTable.IsExist<User>().Execute()
如果存在则删除数据表 Table.DropIfExist<TClass>() void _sqlserverTable.DropIfExist<User>().Execute()
创建数据表 Table.Create<TClass>() void _sqlserverTable.Create<User>().Execute()
获取当前数据库中用户表信息 Table.GetUserTablesInCurrentDatabase() IEnumerable<TableModel> _sqlserverTable.GetUserTablesInCurrentDatabase().Execute()
获取表结构 Table.GetStructure(Type type) IEnumerable<ColumnModel> _sqlserverTable.GetStructure(typeof(User)).Execute()
删除数据表 Table.Drop<TClass>() void _sqlserverTable.Drop<User>().Execute()
如果不存在则创建数据表 Table.CreateIfNotExist<TClass>() void _sqlserverTable.CreateIfNotExist<User>().Execute()
限制和局限
  • 用DataExpress创建SQLite数据表时的列备注只适用于DataExpress读取其内容。不能确保使用其他ORM框架或可视化工具可以读取列备注。
  • Access不支持创建数据表时添加列备注。可使用Access的可视化工具修改列备注。
  • Access不支持触发器所以不能在建表时设置自动更新时间的列。可使用Access的可视化工具设置“宏”,或用数据插入方法或数据更新方法中的参数主动更新时间列。

映射实体类可使用的特性标签

名称 说明 示例 命名空间
[Table] 表示类将映射到的数据库表。 [Table("user", Schema = "Database1")] System.ComponentModel.DataAnnotations.Schema
[ComplexType] 表示该类是复杂类型。 复杂类型是实体类型的非标量属性,实体类型允许在实体内组织标量属性。 复杂类型没有键,并且实体框架不能脱离父对象来管理复杂类型。 [ComplexType] System.ComponentModel.DataAnnotations.Schema
[Index] 指定要在数据库中生成的索引。 [Index(nameof(Isbn), IsUnique=true, Name="Unique_Isbn")] DataExpress.Attributes

映射实体类属性可使用的特性标签

名称 说明 示例 命名空间
[Column] 表示属性将映射到的数据库列。 [Column(Order = 1)] System.ComponentModel.DataAnnotations.Schema
[DatabaseGenerated] 指定数据库生成属性值的方式。 [DatabaseGenerated(DatabaseGeneratedOption.Identity)] System.ComponentModel.DataAnnotations.Schema
[DefaultValue] 指定属性的默认值。 [DefaultValue("CURRENT_TIMESTAMP")] System.ComponentModel
[Description] 指定属性或事件的说明。 [Description("name")] System.ComponentModel
[ForeignKey] 指定哪个属性是关系中的外键。在依赖类的外键属性上,传入导航属性的名称。 [ForeignKey("User")] System.ComponentModel.DataAnnotations.Schema
[NotMapped] 表示应从数据库映射中排除属性或类。 [NotMapped] System.ComponentModel.DataAnnotations.Schema
[Key] 表示唯一标识实体的一个或多个属性。 [Key] System.ComponentModel.DataAnnotations
[Required] 指定数据字段值是必需的。 [Required] System.ComponentModel.DataAnnotations
[MaxLength] 指定属性中允许的数组或字符串数据的最大长度。 [MaxLength(100)] System.ComponentModel.DataAnnotations
[StringLength] 指定数据字段中允许的字符的最小长度和最大长度。 [StringLength(100)] System.ComponentModel.DataAnnotations
[Precision] 配置此属性中允许的数据的精度。 [Precision(10,2)] DataExpress.Attributes
  1. 关于实体类属性(具有 Getter 和 Setter 的实体类型的公共属性):
    • 带有[ComplexType]标签的单一实体类,按照复杂属性处理。
    • 集合实体类属性、不带有[ComplexType]标签的单一实体类,按照内部默认设定名称、顺序,类型为Json。
  2. 关于[NotMapped]:按照约定,所有具有 Getter 和 Setter 的公共属性都将包含在模型中,所以对于所有不需要映射到数据表中的属性都应标注[NotMapped]特性。
  3. 关于[Column]特性:由于不同数据库对列类型的名称解释不同,如果[Column]特性中没有设置TypeName属性值,数据快车会根据不同的数据库,将类的属性类型自动映射为DE内部默认设定名称、顺序、类型,长度和精度。
  4. 关于字符列长度:为了尽量兼容,对[MaxLength][StringLength]都会被识别,当同时出现时优先级为:MaxLength>StringLength>Column.TypeName
  5. 关于必填:[Key]标识的属性映射为必填主键字段,无需再添加[Required]特性。
  6. 关于默认值:因为DBFirst模式下允许用户通过输入表名的方式指定创建的Model,此时不能根据类型创建实体对象,进而无法通过对象获取默认值,所以需要使用[DefaultValue]标签来标注默认值。
  7. 关于数字列精度:精度的优先级:Precision>Column.TypeName
  8. 关于数据自动生成: |枚举名称|枚举值|说明| |-|:-:|-| |DatabaseGeneratedOption.None|0|数据库不生成值。| |DatabaseGeneratedOption.Identity|1|在插入一个行时,数据库会生成一个值。| |DatabaseGeneratedOption.Computed|2|在插入或更新一个行时,数据库会生成一个值。|
  9. [ForeignKey]示例:
    public class User
    {
        public int Id { get; set; }
        ...
        public List<Order> Orders { get; set; }
    }
    
    public class Order
    {
        public int OrderId { get; set; }
    
        [ForeignKey(nameof(Seller))]
        public int SellerId { get; set; }
    
        [ForeignKey(nameof(Buyer))]
        public int BuyerId { get; set; }
        ...
        public User Seller { get; set; }
    
        public User Buyer { get; set; }
    }
    

实体类模型示例

  • 操作记录的示例使用以下3个模型进行演示:
public class ModelBase
{
    /// <summary>
    /// 标识
    /// </summary>
    [Column(Order = 0)]
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public long Id { get; set; }

    /// <summary>
    /// 备注
    /// </summary>
    public string Remarks { get; set; } = string.Empty;

    /// <summary>
    /// 删除状态: 0.未删除,1.已删除
    /// </summary>
    public bool IsDeleted { get; set; } = false;

    /// <summary>
    /// 创建人
    /// </summary>
    [ForeignKey(nameof(CreateByUser))]
    public long CreateBy { get; set; }

    public User? CreateByUser { get; set; }

    /// <summary>
    /// 创建时间
    /// </summary>
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Required]
    public DateTime CreateAt { get; set; }

    /// <summary>
    /// 创建环境
    /// </summary>
    public ClientEnv? CreateEnv { get; set; }

    /// <summary>
    /// 更新人
    /// </summary>
    public long UpdateBy { get; set; }

    /// <summary>
    /// 更新时间
    /// </summary>
    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    [Required]
    public DateTime UpdateAt { get; set; }

    /// <summary>
    /// 更新环境
    /// </summary>
    public ClientEnv? UpdateEnv { get; set; }
}

public class User : ModelBase
{
    /// <summary>
    /// 拼音简码
    /// </summary>
    public string Acronym { get; set; } = string.Empty;

    /// <summary>
    /// 推荐人id
    /// </summary>
    [ForeignKey(nameof(Parent))]
    public long ParentId { get; set; }

    [NotMapped]
    public User? Parent { get; set; }

    /// <summary>
    /// 组织id
    /// </summary>
    [ForeignKey(nameof(Org))]
    public long OrgId { get; set; }

    public Organization? Org { get; set; }

    public List<Organization>? Orgs { get; set; }

    /// <summary>
    /// 用户名
    /// </summary>
    public string UserName { get; set; } = string.Empty;

    /// <summary>
    /// 登录密码
    /// </summary>
    public string LoginPwd { get; set; } = string.Empty;

    /// <summary>
    /// 支付密码
    /// </summary>
    public string PayPwd { get; set; } = string.Empty;

    /// <summary>
    /// 电子邮箱地址
    /// </summary>
    public string Email { get; set; } = string.Empty;

    /// <summary>
    /// 手机号
    /// </summary>
    public string Mobile { get; set; } = string.Empty;

    /// <summary>
    /// 用户等级
    /// </summary>
    public byte Level { get; set; }

    /// <summary>
    /// 头像
    /// </summary>
    public string Avatar { get; set; } = string.Empty;

    /// <summary>
    /// 语言
    /// </summary>
    public byte LanguageId { get; set; }

    /// <summary>
    /// 认证状态:0.未通过 1.已通过
    /// </summary>
    public bool IsAuthenticated { get; set; } = false;
    /// <summary>
    /// 是否禁用: 0.未禁用,1.已禁用
    /// </summary>
    public bool IsDisabled { get; set; } = false;

    /// <summary>
    /// 真实姓名
    /// </summary>
    public string RealName { get; set; } = string.Empty;

    /// <summary>
    /// 出生国家
    /// </summary>
    public string CountryOfBirth { get; set; } = string.Empty;

    /// <summary>
    /// 出生省份
    /// </summary>
    public string ProvinceOfBirth { get; set; } = string.Empty;

    /// <summary>
    /// 出生城市
    /// </summary>
    public string PrefectureOfBirth { get; set; } = string.Empty;

    /// <summary>
    /// 出生区、县
    /// </summary>
    public string DistrictOfBirth { get; set; } = string.Empty;

    /// <summary>
    /// 出生日期
    /// </summary>
    public DateTime DateOfBirth { get; set; } = new(0001, 01, 01);

    /// <summary>
    /// 性别:0.未知 1.男 2.女
    /// </summary>
    public byte Gender { get; set; }

    /// <summary>
    /// 户籍地址
    /// </summary>
    public Address? AddressOfReg { get; set; }

    /// <summary>
    /// 民族
    /// </summary>
    public string Nation { get; set; } = string.Empty;

    /// <summary>
    /// 血型:0.未知 1.A 2.B 3.AB 4.O
    /// </summary>
    public byte BloodType { get; set; }

    /// <summary>
    /// 身份证件
    /// </summary>
    public PersonalId? PersonalId { get; set; }
}

/// <summary>
/// 地址
/// </summary>
[ComplexType]
public class Address
{
    /// <summary>
    /// 中文
    /// </summary>
    public string Cn { get; set; } = string.Empty;

    /// <summary>
    /// 英文
    /// </summary>
    public string En { get; set; } = string.Empty;

    /// <summary>
    /// 国家
    /// </summary>
    public string Country { get; set; } = string.Empty;

    /// <summary>
    /// 省或州
    /// </summary>
    public string ProvinceOrState { get; set; } = string.Empty;

    /// <summary>
    /// 城市
    /// </summary>
    public string City { get; set; } = string.Empty;

    /// <summary>
    /// 区或县
    /// </summary>
    public string DistrictOrCounty { get; set; } = string.Empty;

    /// <summary>
    /// 街道或乡镇
    /// </summary>
    public string SubdistrictOrTown { get; set; } = string.Empty;

    /// <summary>
    /// 道路
    /// </summary>
    public string Street { get; set; } = string.Empty;

    /// <summary>
    /// 门牌号
    /// </summary>
    public string Number { get; set; } = string.Empty;
}

[ComplexType]
public class PersonalId
{
    [Description("证件类型:0.未知 1.身份证 2.护照")]
    [Required]
    [DefaultValue(0)]
    public int CategoryId { get; set; } = 0;

    public string Category { get; set; } = string.Empty;

    [Description("证件号")]
    [Required]
    [StringLength(18)]
    [DefaultValue("")]
    [Column(TypeName = "char")]
    public string Number { get; set; } = string.Empty;


    [Description("开始日期")]
    [Required]
    [Column(TypeName = "date")]
    [DefaultValue("0001-01-01")]
    public DateTime DateOfStart { get; set; } = new(0001, 01, 01);

    [Description("结束日期")]
    [Required]
    [Column(TypeName = "date")]
    [DefaultValue("0001-01-01")]
    public DateTime DateOfEnd { get; set; } = new(0001, 01, 01);


    [Description("发证机构")]
    [Required]
    [StringLength(100)]
    [DefaultValue("")]
    public string IssuingAuthority { get; set; } = string.Empty;

    [Description("正面")]
    [Required]
    [StringLength(100)]
    [DefaultValue("")]
    public string ImgA { get; set; } = string.Empty;

    [Description("反面")]
    [Required]
    [StringLength(100)]
    [DefaultValue("")]
    public string ImgB { get; set; } = string.Empty;
}

public class ClientEnv
{
    public string Os { get; set; } = string.Empty;

    public string OsVersion { get; set; } = string.Empty;

    public string Browser { get; set; } = string.Empty;

    public string BrowserVersion { get; set; } = string.Empty;

    public string Ip { get; set; } = string.Empty;

    public string IpLocation { get; set; } = string.Empty;

    public string DeviceType { get; set; } = string.Empty;

    public string Resolution { get; set; } = string.Empty;

    public string Language { get; set; } = string.Empty;
}

对数据记录的编辑

Access默认不支持long类型的数据,虽然Access2016以上版本可以手动开启,但为了兼容没有开启支持的数据库,所有long类型会自动转化为int类型进行持久化保存。

清空数据表

Table.Truncate 方法

方法说明 方法 返回值类型 SQL Server MySQL SQLite Access 示例
清空数据表 Table.Truncate<TClass>() void _sqlserverTable.Truncate<User>().Execute()

插入数据

Table.Insert 方法
  • 使用匿名对象、Lambda表达式、实体对象做为参数插入单一记录,也可以用List<TClass>型参数批量插入多条记录,或从csv文件导入数据。
  • 插入一条记录时返回自增主键值,如果主键不是自增长返回0。插入多条记录时返回影响行数。
SQL Server MySQL SQLite Access
使用匿名对象插入数据
使用表达式插入数据
使用实体对象插入数据
批量插入数据
从csv文件导入数据 × ×
示例
//使用匿名类对象插入一条数据。
//Insert 1 record using anonymous class object.
int ins1 = _sqlserverTable.Insert<User>(new { UserName = "匿名对象插入", AddressOfReg = new { City = "天津", DistrictOrCounty = "河东区" } }).Execute();

//使用Lambda表达式插入一条数据。
//Insert 1 record using lambda expression.
int ins2 = _sqlserverTable.Insert<User>(u => new User() { UserName = "表达式插入", AddressOfReg = new Address { City = "天津", DistrictOrCounty = "河东区" } }).Execute();

//使用实体类对象插入一条数据。(可省略<TClass>)
//Insert 1 record using entity class object.
int int3 = _sqlserverTable.Insert(new User { UserName = "实体对象插入", AddressOfReg = new Address { City = "天津", DistrictOrCounty = "河东区" } }).Execute();

//批量插入数据。
//Insert data in bulk using collection.
int int4 = _sqlserverTable.Insert<User>(new List<User>
{
    new() { UserName = "批量插入1", AddressOfReg = new Address { City = "天津", DistrictOrCounty = "和平区" } },
    new() { UserName = "批量插入2", AddressOfReg = new Address { City = "天津", DistrictOrCounty = "河东区" } },
    new() { UserName = "批量插入3", AddressOfReg = new Address { City = "天津", DistrictOrCounty = "河西区" } },
    new() { UserName = "批量插入4", AddressOfReg = new Address { City = "天津", DistrictOrCounty = "南开区" } },
    new() { UserName = "批量插入5", AddressOfReg = new Address { City = "天津", DistrictOrCounty = "河北区" } },
    new() { UserName = "批量插入6", AddressOfReg = new Address { City = "天津", DistrictOrCounty = "红桥区" } },
    new() { UserName = "批量插入7", AddressOfReg = new Address { City = "天津", DistrictOrCounty = "东丽区" } },
    new() { UserName = "批量插入8", AddressOfReg = new Address { City = "天津", DistrictOrCounty = "西青区" } },
    new() { UserName = "批量插入9", AddressOfReg = new Address { City = "天津", DistrictOrCounty = "津南区" } },
    new() { UserName = "批量插入10", AddressOfReg = new Address { City = "天津", DistrictOrCounty = "北辰区" } },
}).Execute();

//从csv文件导入数据
//Import data from a CSV file.
int int5 = _sqlserverTable.Insert(@"D\datas.csv");

更新数据

Table.Update 方法
  • 使用匿名对象、Lambda表达式、实体对象作为参数修改记录,返回更新的记录数量。
  • 使用数值字段以当前数值为基数,进行加减乘除等运算结果更新。
  • 使用实体类对象修改数据时,未赋值的属性会将映射的字段值更新为默认值。
  • 带有[DatabaseGeneratedOption.Computed]特性的属性值将不会被更新到数据库中。
SQL Server MySQL SQLite Access
使用实体对象修改数据
使用匿名对象修改数据
用表达式修改设定数据
用表达式修改计算数据
示例
//使用匿名类对象更新数据。
//Update records using anonymous class object.
int upd1 = _sqlserverTable.Update<User>(new { UserName = "匿名对象修改", AddressOfReg = new { City = "天津", DistrictOrCounty = "和平区" } }).Where(u => u.Id == 1).Execute();

//使用Lambda表达式更新记录。
//Update records using lambda expression.
int upd2 = _sqlserverTable.Update<User>(u => new User() { UserName = "表达式修改", AddressOfReg = new Address { City = "天津", DistrictOrCounty = "河东区" } }).Where(u => u.Id == 2).Execute();

//使用实体类对象更新数据。
//Update records using entity class object.
int upd3 = _sqlserverTable.Update<User>(new User() { UserName = "实体对象修改", AddressOfReg = new Address { City = "天津", DistrictOrCounty = "河西区" } }).Where(u => u.Id == 3).Execute();

//使用Lambda表达式更新计算数据。
//Update calculated data using lambda expression.
int upd4 = _sqlserverTable.Update<User>(x => new User { Level = (byte)(x.Level + 1) }).Where(x => x.Id == 4).Execute();

删除数据

Table.Delete 方法
  • 使用匿名对象做为参数删除记录,也可以用Where()方法作为筛选条件删除记录,返回删除的记录数量。
  • 如果使用匿名对象为参数筛选记录时同时使用Where()方法,对象中与表达式中相同名称的筛选用条件属性会被覆盖,不重复的条件属性将进行AND合并。
SQL Server MySQL SQLite Access
用Where方法删除数据
用匿名对象删除数据
示例
//用匿名对象删除数据。
//Delete records using anonymous class object.
int del1 = _sqlserverTable.Delete<User>(new { Id = 5 }).Execute();

//用Where方法删除数据。
//Delete records using "Where" method.
int del2 = _sqlserverTable.Delete<User>().Where(u => new long[] { 6, 7, 8, 9, 10 }.Contains(u.Id)).Execute();

插入模拟数据

Table.InsertMock 方法

  • 向数据表中添加指定数量用于开发和测试的模拟数据。
SQL Server MySQL SQLite Access
插入模拟数据
设置模拟数据

InsertMock<TClass>(DataExpress.Table, DataExpress.Utils.Country, int) public static InsertMockContext<TClass> InsertMock<TClass>(this Table table, Country country, int count = 100)

参数

table DataExpress.Table 操作数据的对象。 country DataExpress.Utils.Country 一个枚举值。指定模拟数据需要遵循的习惯的国家。 count int 指定插入模拟数据的数量,默认值为100。

示例
_sqlserverTable.InsertMock<User>(Country.中国, count).Execute();

InsertMockContext<TClass>.SetMock 方法

  • 使用SetMock()扩展方法和MockCategory枚举,对将要插入的模拟数据进行详细设置。

SetMock<TClass>(InsertMockContext<TClass>, Expression<Func<TClass, object>>, MockCategory, Country, IEnumerable<object>, IEnumerable<object>, HashCategory) public static InsertMockContext<TClass> SetMock<TClass>(this InsertMockContext<TClass> context, Expression<Func<TClass, object>> columnExpression, MockCategory mockCategory, Country country = Country.Undefined, IEnumerable<object> ranges = null, HashCategory hashCategory = HashCategory.Undefined)

参数

context InsertMockContext<TClass> 操作数据的上下文。 columnExpression Expression<Func<TClass, object>> 用来选择被设置的列的Lambda表达式。 mockCategory DataExpress.Utils.MockCategory 一个枚举值。指定插入模拟数据的种类。 country DataExpress.Utils.Country 一个枚举值。指定模拟数据需要遵循的习惯的国家。该参数允许指定列重置InsertMock<TClass>()中的Country参数。 ranges IEnumerable<object> 自定义随机值的来源范围。 hashCategory DataExpress.Utils.HashCategory 生成的模拟数据是否要进行摘要处理。例如Password字段。

示例
var envLIst = new List<ClientEnv>
{
    new() { Os = "Windows", OsVersion = "10", Browser = "Edge" },
    new() { Os = "Windows", OsVersion = "7", Browser = "IE" },
    new() { Os = "IOS", OsVersion = "18", Browser = "Safari" },
    new() { Os = "Android", OsVersion = "12", Browser = "Chrome" }
};

_sqlserverTable.InsertMock<User>(Country.中国, 1000)
    .SetMock(x => x.ParentId, MockCategory.Range_自定义范围, Country.Undefined, [1..100])
    .SetMock(x => x.OrgId, MockCategory.Range_自定义范围, Country.Undefined, [1..100])
    .SetMock(x => x.LoginPwd, MockCategory.Range_自定义范围, Country.Undefined, ["000000"], HashCategory.MD5)
    .SetMock(x => x.PayPwd, MockCategory.Range_自定义范围, Country.Undefined, ["000000"], HashCategory.MD5)
    .SetMock(x => x.Email, MockCategory.Email_电子邮箱)
    .SetMock(x => x.Mobile, MockCategory.Mobile_移动电话号)
    .SetMock(x => x.Level, MockCategory.Range_自定义范围, Country.Undefined, [0, 1, 2, 3, 4, 5])
    .SetMock(x => x.IsAuthenticated, MockCategory.Range_自定义范围, Country.Undefined, [true, false])
    .SetMock(x => x.RealName, MockCategory.PersonName_姓名)
    .SetMock(x => x.CountryOfBirth, MockCategory.Range_自定义范围, Country.Undefined, ["中国"])
    .SetMock(x => x.ProvinceOfBirth, MockCategory.ProvinceName_省级行政区名)
    .SetMock(x => x.PrefectureOfBirth, MockCategory.PrefectureName_地级行政区名)
    .SetMock(x => x.DistrictOfBirth, MockCategory.CountyName_县级行政区名)
    .SetMock(x => x.DateOfBirth, MockCategory.DateOfBirth_出生日期)
    .SetMock(x => x.Gender, MockCategory.Range_自定义范围, Country.Undefined, [0, 1, 2])
    .SetMock(x => x.BloodType, MockCategory.Range_自定义范围, Country.Undefined, [0, 1, 2, 3, 4])
    .SetMock(x => x.AddressOfReg.ProvinceOrState, MockCategory.ProvinceName_省级行政区名)
    .SetMock(x => x.AddressOfReg.City, MockCategory.PrefectureName_地级行政区名)
    .SetMock(x => x.AddressOfReg.DistrictOrCounty, MockCategory.CountyName_县级行政区名)
    .SetMock(x => x.AddressOfReg.Cn, MockCategory.ResidentialAddress_住宅地址)
    .SetMock(x => x.PersonalId.CategoryId, MockCategory.Range_自定义范围, Country.Undefined, [0..2])
    .SetMock(x => x.PersonalId.Number, MockCategory.PersonIdNumber_身份证号)
    .SetMock(x => x.PersonalId.IssuingAuthority, MockCategory.Range_自定义范围, Country.Undefined, ["天津和平分局", "天津河东分局", "天津河西分局"])
    .SetMock(x => x.IsDeleted, MockCategory.Range_自定义范围, Country.Undefined, [true, false])
    .SetMock(x => x.CreateBy, MockCategory.Range_自定义范围, Country.Undefined, [1..100])
    .SetMock(x => x.UpdateBy, MockCategory.Range_自定义范围, Country.Undefined, [1..100])
    .SetMock(x => x.CreateEnv, MockCategory.Range_自定义范围, Country.Undefined, envLIst)
    .SetMock(x => x.UpdateEnv, MockCategory.Range_自定义范围, Country.Undefined, envLIst)
    .Execute();

使用事务

示例
try
{
    _sqlserverTable.BeginTransaction();
    ...
    _sqlserverTable.Commit();
}
catch (Exception ex)
{
    _sqlserverTable.Rollback();
    //Write to log;
}

对数据记录的查询

  • 使用Lambda表达式及实体类进行数据查询,返回强类型对象集合。
  • 查询的执行顺序:查询(包括递归)(Select & Recursive)-> 筛选、分组与排序(Where & GroupBy & OrderBy) → 分页(Paging) → 联接(Join)
方法 SQL Server MySQL SQLite Access
数据查询 Table.Select<TFirst>()
递归查询 Recursive<TFirst...TSixteenth>() 9.0(2005)+ 8.0+ 3.8.3+ ×
数据筛选 Where<TFirst...TSixteenth>()
数据排序 OrderBy<TFirst...TSixteenth>()
数据分页 Paging<TFirst...TSixteenth>()
数据联接 Join<TFirst...TSixteenth>()

单表查询

//查询全部字段
IEnumerable<User> result1 = _sqlserverTable.Select<User>()
    .Where(u => u.Level > 3 && u.IsDeleted == false)
    .OrderBy(u => u.Id, true)
    .Page(1, 10)
    .Execute();

//查询指定字段
IEnumerable<User> result2 = _sqlserverTable.Select<User>(u => new { u.Id, u.UserName, u.Email, u.IsDeleted })
    .Where(u => u.Level > 3 && u.IsDeleted == false)
    .OrderBy(u => u.Id, true)
    .Page(1, 10)
    .Execute();

查询值对象或Json列

//查询值对象或Json列
IEnumerable<User> result1 = _sqlserverTable.Select<User>(u => new { u.Id, u.UserName, u.Email, u.IsDeleted, u.AddressOfReg, u.CreateEnv })
    .Where(u => u.Level > 3 && u.IsDeleted == false)
    .OrderBy(u => u.Id, true)
    .Page(1, 10)
    .Execute();

条件函数

示例
IEnumerable<User> result1 = _sqlserverTable.Select<User>(x => new { x.Id, Category = x.PersonalId.CategoryId == 1 ? "身份证" : "其它" })
    .Execute();

IEnumerable<User> result2 = _sqlserverTable.Select<Organization>(x => new { x.Id, NameCn = string.IsNullOrEmpty(x.NameCn) ? "第一" : "第二" })
    .Execute();

IEnumerable<User> result3 = _sqlserverTable.Select<Organization>(x => new { x.Id, NameCn = new long[] { 1, 2, 3, 4 }.Contains(x.Id) ? "第一" : "第二" })
    .Execute();
限制与局限
  • 由于Lambda表达式的new方法中被设置的匿名类型成员必须使用成员赋值、简单名称或成员访问来声明,被设置的属性必须与条件中的属性在同一个父类中,这样可以用条件中的第一个属性作为参照形成结果列信息,所以如果是不同父类则无法使用。例如想使用复杂属性类的Name属性作为条件,来操作其所在实体类中的Name属性是不被支持的。

聚合函数

var result1 = _sqlserverTable.Select<User>(x => new { Level = SqlFunc.Avg(x.Level) }).Where(u.IsDeleted == false).Execute();
var result2 = _sqlserverTable.Select<User>(x => new { Level = SqlFunc.Count(x.Level) }).Where(u.IsDeleted == false).Execute();
var result3 = _sqlserverTable.Select<User>(x => new { Level = SqlFunc.Max(x.Level) }).Where(u.IsDeleted == false).Execute();
var result4 = _sqlserverTable.Select<User>(x => new { Level = SqlFunc.Min(x.Level) }).Where(u.IsDeleted == false).Execute();
var result5 = _sqlserverTable.Select<User>(x => new { Level = SqlFunc.Sum(x.Level) }).Where(u.IsDeleted == false).Execute();

递归查询

Recursive 方法
  • 使用Recursive()扩展方法进行递归查询。

Recursive<TFirst>(SelectContext<TFirst>, Expression<Func<TFirst, object>>, Expression<Func<TFirst, object>>, uint?) public static SelectContext<TFirst> Recursive<TFirst>(this SelectContext<TFirst> context, Expression<Func<TFirst, object>> initialCondition, Expression<Func<TFirst, object>> stopCondition, uint? maxRecursion = null)

参数

context SelectContext<TFirst> 操作数据的上下文。 initialCondition Expression<Func<TFirst, object>> 表示递归初始条件的Lambda表达式。 stopCondition Expression<Func<TFirst, object>> 表示递归结束条件的Lambda表达式。 maxRecursion uint? 递归最大深度。

示例
var result = sqlserverTable.Select<User>(u => new { u.Id, u.ParentId, u.OrgId, u.Email, u.Mobile, u.RealName, u.CreateBy })
    .Recursive(a => a.BloodType == 4, x => x.ParentId == x.Id, 1000)
    .Execute();
限制和局限
  • 由于递归查询将会调用通用表表达式(CET),所以不低于以下版本的数据库均可以使用Select<TClass>().Recursive()方法来使用这项功能: |数据库品牌|版本|发行时间| |-|-|-| |SQLServer|9.0(SQL Server 2005)|2005年11月| |MySQL|8.0|2018年4月8日| |SQLite|3.8.3|2014年2月3日| |Access|不支持|未知|

  • 不能使用DataExpress递归查询的数据库,可以使用LEFT JOIN来将表与自身连接实现类似功能。例如: Select<User>(a => new { a.Id, a.ParentId, a.Email }) .Join<User>(JoinType.Left, (a, b) => a.ParentId == b.Id, b => new { b.Id, b.ParentId, b.Email }) .Where((a, b) => a.Id > 2)

筛选

Where 方法
  • 使用Where()扩展方法在查询记录时进行筛选。

Where<TFirst>(SelectContext<TFirst>, Expression<Func<TFirst, object>>, Expression<Func<TFirst, object>>) public static SelectContext<TFirst> Where<TFirst>(this SelectContext<TFirst> context, Expression<Func<TFirst, object>> filteringCondition)

参数

context SelectContext<TFirst> 操作数据的上下文。 filteringCondition Expression<Func<TFirst, object>> 表示筛选条件的Lambda表达式。

示例
IEnumerable<User> result = _sqlserverTable.Select<User>(u => new { u.Id, u.UserName, u.Email, u.IsDeleted })
    .Where(u => u.UserName.Contains("1"))
    .Execute();

表达式可使用的运算符包括: |运算符|使用示例| |:-:|-| |==|u.Id == "1"|| |!=|u.RealName != "Tom"|| |<|u.Age < 30|| |<=|u.Age <= 30|| |>|u.Age > 30|| |>=|u.Age >= 30|| |&&|u.RealName == "Tom" && u.Age == 30|| |\|\||u.RealName == "Tom" \|\| u.Age == 30|| |StartsWith|u.RealName.StartsWith("T")|| |EndsWith|u.RealName.EndsWith("m")|| |Contains|u.RealName.Contains("T")<br>new[] { 1, 2, 3, 4 }.Contains(u.Id)<br>Enumerable.Contains<int>(new[] { 1, 2, 3, }, u.Age)<br>Enumerable.Contains<string>(new[] { "Tom", "Jerry" }, u.Name)|| |Substring|u.RealName.Substring(0, 1) == "T"|| |IndexOf|u.RealName.IndexOf("T", 1) == 1||

跨列筛选

Where 方法
  • 使用Where()扩展方法在查询记录时进行同一条件的多列筛选。

Where<TFirst>(SelectContext<TFirst>, Expression<Func<TFirst, object>>, Expression<Func<TFirst, object>>) public static SelectContext<TFirst> Where<TFirst>(this SelectContext<TFirst> context, Expression<Func<TFirst, object>> filteringCondition, Expression<Func<TFirst, object>> expandColumns = null)

参数

context SelectContext<TFirst> 操作数据的上下文。 filteringCondition Expression<Func<TFirst, object>> 表示筛选条件的Lambda表达式。 expandColumns Expression<Func<TFirst, object>> 表示将筛选条件扩展到其他列的Lambda表达式。

示例
IEnumerable<User> result = _sqlserverTable.Select<User>(u => new { u.Id, u.UserName, u.Email, u.IsDeleted })
    .Where(u => u.UserName.Contains("1"), u => new { u.Id, u.AddressOfReg.City })
    .Execute();

分组

  • 在Select<TClass>()的Lambda表达式参数中,如果对某一个或多个属性设置使用聚合函数,则其他未设置聚合函数的属性将被作为用来分组的字段。
示例
//用“Gender”进行分组,并计算“Lever”列的最大值。
IEnumerable<User> result = _sqlserverTable.Select<User>(x => new { x.Gender, Level = SqlFunc.Max(x.Level) })
    .Where(u.IsDeleted == false)
    .Execute();

排序

OrderBy 方法
  • 使用OrderBy()扩展方法在查询记录时进行筛选。

OrderBy<TClass>(SelectContext<TClass>, Expression<Func<TClass, object>>, bool) public static SelectContext<TClass> OrderBy<TClass>(this SelectContext<TClass> context, Expression<Func<TClass, object>> sortingCondition, bool isReverse = false)

参数

context SelectContext<TFirst> 操作数据的上下文。 sortingCondition Expression<Func<TFirst, object>> 表示排序条件的Lambda表达式。 isReverse bool 是否倒序。

示例
IEnumerable<User> result = _sqlserverTable.Select<User>(u => new { u.Id, u.UserName, u.Email, u.IsDeleted })
    .OrderBy(u => u.Id, true)
    .Execute();

分页

Page 方法
  • 使用Page()扩展方法在查询记录时进行记录范围设置。

Page<TClass>(SelectContext<TClass>, uint, uint) public static SelectContext<TClass> Page<TClass>(this SelectContext<TClass> context, uint pageIndex, uint pageSize)

参数

context SelectContext<TFirst> 操作数据的上下文。 pageIndex uint 页码。 pageSize uint 每页记录数量。

示例
IEnumerable<User> result = _sqlserverTable.Select<User>(u => new { u.Id, u.UserName, u.Email, u.IsDeleted })
    .OrderBy(u => u.Id, true)
    .Page(5, 10)
    .Execute();

多表查询

Join 方法
  • 使用Join方法进行多表联合查询。 Join<TSecond>(JoinType, Expression<Func<TFirst, TSecond, bool>>, Expression<Func<TSecond, object>>) public SelectContext<TFirst, TSecond> Join<TSecond>(JoinType joinType, Expression<Func<TFirst, TSecond, bool>> conditionExpression, Expression<Func<TSecond, object>> columnExpression = null)
参数

joinType JoinType 表示Join类型的枚举值。 conditionExpression Expression<Func<TFirst, TSecond, bool>> 表示联合条件的Lambda表达式。 columnExpression Expression<Func<TFirst, TSecond, bool>> 可选参数,表示查询列的Lambda表达式,如果为空则会查询全部列。

示例
IEnumerable<User> result = _sqlserverTable.Select<User>(u => new { u.Id, u.ParentId, u.OrgId, u.Email, u.Mobile, u.RealName, u.CreateBy })
    .Where(a => a.Level > 1)
    .OrderBy(a => a.Id, true)
    .OrderBy(a => a.ParentId, true)
    .Page(1, 10)
    .Join<Organization>(JoinType.Left, (a, b) => a.OrgId == b.Id, b => new { b.Id, b.NameCn })
    .Join<User>(JoinType.Left, (a, b, c) => a.CreateBy == c.Id, u => new { u.Id, u.ParentId, u.Email, u.Mobile, u.RealName })
    .Execute();

联合主键

Join 方法
  • 使用Join方法,在conditionExpression参数中使用多个属性进行多表联合查询。

跨库查询

  • 通过在Model的类标签[Table]设置“Schema”属性值来指定表所属的模式名称,即可实现跨数据库查询。例如:
[Table("order", Schema = "db2")]
public class Order
{
    ...
}

联系我们

email:cnxl@hotmail.com

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  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 was computed.  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 was computed.  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 netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.0.1-alpha01 104 12/13/2024

An ORM library for DDD pattern design. SQL Server, MySQL, SQLite, and Access are supported. Supports the generation of simulation data for testing.
适用 DDD 模式设计的 ORM 库。支持 SQL Server、MySQL、SQLite 和 Access。支持生成测试用的仿真数据。