mirror of
https://gitee.com/dotnetchina/SqlSugar.git
synced 2025-11-18 16:59:03 +08:00
Add DuckDB
This commit is contained in:
134
Src/Asp.NetCore2/DuckDBTest/1_CodeFirst.cs
Normal file
134
Src/Asp.NetCore2/DuckDBTest/1_CodeFirst.cs
Normal file
@@ -0,0 +1,134 @@
|
||||
using SqlSugar;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OrmTest
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for demonstrating CodeFirst initialization operations
|
||||
/// 用于展示 CodeFirst 初始化操作的类
|
||||
/// </summary>
|
||||
public class _1_CodeFirst
|
||||
{
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
// Get a new database instance
|
||||
// 获取新的数据库实例
|
||||
var db = DbHelper.GetNewDb();
|
||||
|
||||
// Create the database if it doesn't exist
|
||||
// 如果数据库不存在,则创建数据库
|
||||
db.DbMaintenance.CreateDatabase();
|
||||
|
||||
// Initialize tables based on UserInfo001 entity class
|
||||
// 根据 UserInfo001 实体类初始化表
|
||||
db.CodeFirst.InitTables<UserInfo001>();
|
||||
|
||||
//Table structure and class are different
|
||||
//表结构和类存在差异 初始化表
|
||||
db.CodeFirst.InitTables<UserInfo002>();
|
||||
|
||||
//Insert
|
||||
//插入
|
||||
var id=db.Insertable(new UserInfo001()
|
||||
{
|
||||
Context = "Context",
|
||||
Email="dfafa@qq.com",
|
||||
Price=Convert.ToDecimal(1.1),
|
||||
UserName="admin",
|
||||
RegistrationDate=DateTime.Now,
|
||||
|
||||
}).ExecuteReturnIdentity();
|
||||
|
||||
//Query
|
||||
//查询
|
||||
var userInfo=db.Queryable<UserInfo001>().InSingle(id);
|
||||
|
||||
//Update
|
||||
//更新
|
||||
db.Updateable(userInfo).ExecuteCommand();
|
||||
|
||||
//Delete
|
||||
//删除
|
||||
db.Deleteable(userInfo).ExecuteCommand();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// User information entity class
|
||||
/// 用户信息实体类
|
||||
/// </summary>
|
||||
public class UserInfo001
|
||||
{
|
||||
/// <summary>
|
||||
/// User ID (Primary Key)
|
||||
/// 用户ID(主键)
|
||||
/// </summary>
|
||||
[SugarColumn(IsIdentity = true, IsPrimaryKey = true)]
|
||||
public int UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// User name
|
||||
/// 用户名
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 50, IsNullable = false)]
|
||||
public string UserName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// User email
|
||||
/// 用户邮箱
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public string Email { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Product price
|
||||
/// 产品价格
|
||||
/// </summary>
|
||||
public decimal Price { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// User context
|
||||
/// 用户内容
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = true)]
|
||||
public string Context { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// User registration date
|
||||
/// 用户注册日期
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public DateTime? RegistrationDate { get; set; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// User information entity class
|
||||
/// 用户信息实体类
|
||||
/// </summary>
|
||||
[SugarTable("UserInfoAAA01")]
|
||||
public class UserInfo002
|
||||
{
|
||||
/// <summary>
|
||||
/// User ID (Primary Key)
|
||||
/// 用户ID(主键)
|
||||
/// </summary>
|
||||
[SugarColumn(IsIdentity = true,ColumnName ="Id", IsPrimaryKey = true)]
|
||||
public int UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// User name
|
||||
/// 用户名
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 50,ColumnName ="Name", IsNullable = false)]
|
||||
public string UserName { get; set; }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
136
Src/Asp.NetCore2/DuckDBTest/2_DbFirst.cs
Normal file
136
Src/Asp.NetCore2/DuckDBTest/2_DbFirst.cs
Normal file
@@ -0,0 +1,136 @@
|
||||
using SqlSugar;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OrmTest
|
||||
{
|
||||
internal class _2_DbFirst
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始化方法,包含各种DbFirst操作的演示
|
||||
/// Initialization method containing demonstrations of various DbFirst operations
|
||||
/// </summary>
|
||||
public static void Init()
|
||||
{
|
||||
var db = DbHelper.GetNewDb();
|
||||
|
||||
// 生成干净的实体类文件
|
||||
// Generate clean entity class files
|
||||
Demo1(db);
|
||||
|
||||
// 生成带有SqlSugar特性的实体类文件
|
||||
// Generate entity class files with SqlSugar attributes
|
||||
Demo2(db);
|
||||
|
||||
// 支持字符串类型的Nullable特性
|
||||
// Support String Nullable attribute
|
||||
Demo3(db);
|
||||
|
||||
// 格式化类名、属性名和文件名
|
||||
// Format class names, property names, and file names
|
||||
Demo4(db);
|
||||
|
||||
// 条件过滤生成实体类文件
|
||||
// Generate entity class files with condition filtering
|
||||
Demo5(db);
|
||||
|
||||
// 修改模版生成实体类文件(禁用IsCreateAttribute,避免冲突)
|
||||
// Generate entity class files with modified templates (disable IsCreateAttribute to avoid conflicts)
|
||||
Demo6(db);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成干净的实体类文件
|
||||
/// Generate clean entity class files
|
||||
/// </summary>
|
||||
private static void Demo1(SqlSugarClient db)
|
||||
{
|
||||
db.DbFirst.CreateClassFile("c:\\Demo\\1", "Models");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成带有SqlSugar特性的实体类文件
|
||||
/// Generate entity class files with SqlSugar attributes
|
||||
/// </summary>
|
||||
private static void Demo2(SqlSugarClient db)
|
||||
{
|
||||
db.DbFirst.IsCreateAttribute().CreateClassFile("c:\\Demo\\2", "Models");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 支持字符串类型的Nullable特性
|
||||
/// Support String Nullable attribute
|
||||
/// </summary>
|
||||
private static void Demo3(SqlSugarClient db)
|
||||
{
|
||||
db.DbFirst.IsCreateAttribute().StringNullable().CreateClassFile("c:\\Demo\\3", "Models");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 格式化类名、属性名和文件名
|
||||
/// Format class names, property names, and file names
|
||||
/// </summary>
|
||||
private static void Demo4(SqlSugarClient db)
|
||||
{
|
||||
db.DbFirst
|
||||
.IsCreateAttribute()
|
||||
.FormatFileName(it => "File_" + it)
|
||||
.FormatClassName(it => "Class_" + it)
|
||||
.FormatPropertyName(it => "Property_" + it)
|
||||
.CreateClassFile("c:\\Demo\\4", "Models");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 条件过滤生成实体类文件
|
||||
/// Generate entity class files with condition filtering
|
||||
/// </summary>
|
||||
private static void Demo5(SqlSugarClient db)
|
||||
{
|
||||
db.DbFirst.IsCreateAttribute().Where(it => it.ToLower() == "userinfo001").CreateClassFile("c:\\Demo\\5", "Models");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改模版生成实体类文件(禁用IsCreateAttribute,避免冲突)
|
||||
/// Generate entity class files with modified templates (disable IsCreateAttribute to avoid conflicts)
|
||||
/// </summary>
|
||||
private static void Demo6(SqlSugarClient db)
|
||||
{
|
||||
db.DbFirst
|
||||
// 类
|
||||
.SettingClassTemplate(old => { return old;/* 修改old值替换 */ })
|
||||
// 类构造函数
|
||||
.SettingConstructorTemplate(old => { return old;/* 修改old值替换 */ })
|
||||
.SettingNamespaceTemplate(old =>
|
||||
{
|
||||
return old + "\r\nusing SqlSugar;"; // 追加引用SqlSugar
|
||||
})
|
||||
// 属性备注
|
||||
.SettingPropertyDescriptionTemplate(old => { return old;/* 修改old值替换 */})
|
||||
|
||||
// 属性:新重载 完全自定义用配置
|
||||
.SettingPropertyTemplate((columns, temp, type) =>
|
||||
{
|
||||
|
||||
var columnattribute = "\r\n [SugarColumn({0})]";
|
||||
List<string> attributes = new List<string>();
|
||||
if (columns.IsPrimarykey)
|
||||
attributes.Add("IsPrimaryKey=true");
|
||||
if (columns.IsIdentity)
|
||||
attributes.Add("IsIdentity=true");
|
||||
if (attributes.Count == 0)
|
||||
{
|
||||
columnattribute = "";
|
||||
}
|
||||
return temp.Replace("{PropertyType}", type)
|
||||
.Replace("{PropertyName}", columns.DbColumnName)
|
||||
.Replace("{SugarColumn}", string.Format(columnattribute, string.Join(",", attributes)));
|
||||
})
|
||||
|
||||
.CreateClassFile("c:\\Demo\\6");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
191
Src/Asp.NetCore2/DuckDBTest/3_EasyQuery.cs
Normal file
191
Src/Asp.NetCore2/DuckDBTest/3_EasyQuery.cs
Normal file
@@ -0,0 +1,191 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SqlSugar;
|
||||
|
||||
namespace OrmTest
|
||||
{
|
||||
internal class _3_EasyQuery
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始化方法,包含各种查询操作的演示
|
||||
/// Initialization method containing demonstrations of various query operations
|
||||
/// </summary>
|
||||
public static void Init()
|
||||
{
|
||||
// 创建表并插入一条记录
|
||||
// Create table and insert a record
|
||||
CreateTable();
|
||||
|
||||
// 查询所有学生信息
|
||||
// Query all student records
|
||||
GetAllStudents();
|
||||
|
||||
// 查询学生总数
|
||||
// Get the total count of students
|
||||
GetStudentCount();
|
||||
|
||||
// 按条件查询学生信息
|
||||
// Query student records based on conditions
|
||||
GetStudentsByCondition();
|
||||
|
||||
// 模糊查询学生信息(名字包含"jack"的学生)
|
||||
// Fuzzy search for student records (students with names containing "jack")
|
||||
GetStudentsByName("jack");
|
||||
|
||||
// 根据学生ID查询单个学生
|
||||
// Query a single student by student ID
|
||||
GetStudentById(1);
|
||||
|
||||
// 获取Student03表中的最大Id
|
||||
// Get the maximum ID from the Student03 table
|
||||
GetMaxStudentId();
|
||||
|
||||
// 简单排序(按照Id降序排序)
|
||||
// Simple sorting (sorting by Id in descending order)
|
||||
GetStudentsOrderedByIdDesc();
|
||||
|
||||
// 查询学生姓名列表
|
||||
// Query the list of student names
|
||||
GetStudentNames();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建表并插入一条记录
|
||||
/// Create table and insert a record
|
||||
/// </summary>
|
||||
private static void CreateTable()
|
||||
{
|
||||
SqlSugarClient db = DbHelper.GetNewDb();
|
||||
db.CodeFirst.InitTables<Student03>();
|
||||
db.Insertable(new Student03() { Name = "name" + SnowFlakeSingle.Instance.NextId() })
|
||||
.ExecuteCommand();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询所有学生信息
|
||||
/// Query all student records
|
||||
/// </summary>
|
||||
private static void GetAllStudents()
|
||||
{
|
||||
SqlSugarClient db = DbHelper.GetNewDb();
|
||||
var students = db.Queryable<Student03>().ToList();
|
||||
// 处理查询结果
|
||||
// Process the query results
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询学生总数
|
||||
/// Get the total count of students
|
||||
/// </summary>
|
||||
private static void GetStudentCount()
|
||||
{
|
||||
SqlSugarClient db = DbHelper.GetNewDb();
|
||||
var count = db.Queryable<Student03>().Count();
|
||||
// 处理查询结果
|
||||
// Process the query results
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按条件查询学生信息
|
||||
/// Query student records based on conditions
|
||||
/// </summary>
|
||||
private static void GetStudentsByCondition()
|
||||
{
|
||||
SqlSugarClient db = DbHelper.GetNewDb();
|
||||
|
||||
// 查询name字段不为null的学生
|
||||
// Query students where the 'name' field is not null
|
||||
var studentsWithNameNotNull = db.Queryable<Student03>().Where(it => it.Name != null).ToList();
|
||||
|
||||
// 查询name字段为null的学生
|
||||
// Query students where the 'name' field is null
|
||||
var studentsWithNameNull = db.Queryable<Student03>().Where(it => it.Name == null).ToList();
|
||||
|
||||
// 查询name字段不为空的学生
|
||||
// Query students where the 'name' field is not empty
|
||||
var studentsWithNameNotEmpty = db.Queryable<Student03>().Where(it => it.Name != "").ToList();
|
||||
|
||||
// 多条件查询
|
||||
// Query students with multiple conditions
|
||||
var studentsWithMultipleConditions = db.Queryable<Student03>().Where(it => it.Id > 10 && it.Name == "a").ToList();
|
||||
|
||||
// 动态OR查询
|
||||
// Dynamic OR query
|
||||
var exp = Expressionable.Create<Student03>();
|
||||
exp.OrIF(true, it => it.Id == 1);
|
||||
exp.Or(it => it.Name.Contains("jack"));
|
||||
var studentsWithDynamicOr = db.Queryable<Student03>().Where(exp.ToExpression()).ToList();
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 模糊查询学生信息
|
||||
/// Fuzzy search for student records
|
||||
/// </summary>
|
||||
private static void GetStudentsByName(string keyword)
|
||||
{
|
||||
SqlSugarClient db = DbHelper.GetNewDb();
|
||||
var students = db.Queryable<Student03>().Where(it => it.Name.Contains(keyword)).ToList();
|
||||
// 处理查询结果
|
||||
// Process the query results
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据学生ID查询单个学生
|
||||
/// Query a single student by student ID
|
||||
/// </summary>
|
||||
private static void GetStudentById(int id)
|
||||
{
|
||||
SqlSugarClient db = DbHelper.GetNewDb();
|
||||
var student = db.Queryable<Student03>().Single(it => it.Id == id);
|
||||
// 处理查询结果
|
||||
// Process the query results
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取Student03表中的最大Id
|
||||
/// Get the maximum ID from the Student03 table
|
||||
/// </summary>
|
||||
private static void GetMaxStudentId()
|
||||
{
|
||||
SqlSugarClient db = DbHelper.GetNewDb();
|
||||
var maxId = db.Queryable<Student03>().Max(it => it.Id);
|
||||
// 处理查询结果
|
||||
// Process the query results
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 简单排序(按照Id降序排序)
|
||||
/// Simple sorting (sorting by Id in descending order)
|
||||
/// </summary>
|
||||
private static void GetStudentsOrderedByIdDesc()
|
||||
{
|
||||
SqlSugarClient db = DbHelper.GetNewDb();
|
||||
var students = db.Queryable<Student03>().OrderBy(sc => sc.Id, OrderByType.Desc).ToList();
|
||||
// 处理查询结果
|
||||
// Process the query results
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询学生姓名列表
|
||||
/// Query the list of student names
|
||||
/// </summary>
|
||||
private static void GetStudentNames()
|
||||
{
|
||||
SqlSugarClient db = DbHelper.GetNewDb();
|
||||
var studentNames = db.Queryable<Student03>().Select(it => it.Name).ToList();
|
||||
// 处理查询结果
|
||||
// Process the query results
|
||||
}
|
||||
|
||||
public class Student03
|
||||
{
|
||||
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
171
Src/Asp.NetCore2/DuckDBTest/4_JoinQuery.cs
Normal file
171
Src/Asp.NetCore2/DuckDBTest/4_JoinQuery.cs
Normal file
@@ -0,0 +1,171 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static OrmTest._4_JoinQuery;
|
||||
|
||||
namespace OrmTest
|
||||
{
|
||||
internal class _4_JoinQuery
|
||||
{
|
||||
public static void Init()
|
||||
{
|
||||
InitializeDatabase();
|
||||
SyntaxSugar1();
|
||||
SyntaxSugar2();
|
||||
SyntaxSugar3();
|
||||
}
|
||||
/// <summary>
|
||||
/// 使用语法糖1进行联表查询。
|
||||
/// Performs a Join query using Syntax Sugar 1.
|
||||
/// </summary>
|
||||
/// <returns>查询结果列表。The list of query results.</returns>
|
||||
public static List<ViewOrder2> SyntaxSugar1()
|
||||
{
|
||||
var db = DbHelper.GetNewDb();
|
||||
var query = db.Queryable<Order>()
|
||||
.LeftJoin<Custom>((o, cus) => o.CustomId == cus.Id)
|
||||
.LeftJoin<OrderDetail>((o, cus, oritem) => o.Id == oritem.OrderId)
|
||||
.Where(o => o.Id == 1)
|
||||
.Select((o, cus, oritem) => new ViewOrder2 { Id = o.Id,Name=o.Name, CustomName = cus.Name })
|
||||
.ToList();
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用语法糖2进行联表查询。
|
||||
/// Performs a Join query using Syntax Sugar 2.
|
||||
/// </summary>
|
||||
/// <returns>查询结果列表。The list of query results.</returns>
|
||||
public static List<Order> SyntaxSugar2()
|
||||
{
|
||||
var db = DbHelper.GetNewDb();
|
||||
var rightQueryable = db.Queryable<Custom>()
|
||||
.LeftJoin<OrderDetail>((o, i) => o.Id == i.Id)
|
||||
.Select(o => o);
|
||||
|
||||
var list = db.Queryable<Order>()
|
||||
.LeftJoin(rightQueryable, (c, j) => c.CustomId == j.Id)
|
||||
.Select(c => c)
|
||||
.ToList();
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用语法糖3进行联表查询。
|
||||
/// Performs a Join query using Syntax Sugar 3.
|
||||
/// </summary>
|
||||
/// <returns>查询结果列表。The list of query results.</returns>
|
||||
public static List<ViewOrder2> SyntaxSugar3()
|
||||
{
|
||||
var db = DbHelper.GetNewDb();
|
||||
var list = db.Queryable<Order, OrderDetail, Custom>((o, i, c) => o.Id == i.OrderId && c.Id == o.CustomId)
|
||||
.Select((o, i, c) => new ViewOrder2 { Id = o.Id, Name = o.Name, CustomName = c.Name })
|
||||
.ToList();
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
static void InitializeDatabase()
|
||||
{
|
||||
// Initialize order data
|
||||
// 初始化订单数据
|
||||
var orders = new List<Order>
|
||||
{
|
||||
new Order { Id = 1, Name = "Order 1", CustomId = 1 },
|
||||
new Order { Id = 2, Name = "Order 2", CustomId = 2 },
|
||||
new Order { Id = 3, Name = "Order 3", CustomId = 1 },
|
||||
};
|
||||
|
||||
// Initialize order details data
|
||||
// 初始化订单详情数据
|
||||
var orderDetails = new List<OrderDetail>
|
||||
{
|
||||
new OrderDetail { Id = 1, OrderId = 1 },
|
||||
new OrderDetail { Id = 2, OrderId = 2 },
|
||||
new OrderDetail { Id = 3, OrderId = 3 },
|
||||
};
|
||||
|
||||
// Initialize customer data
|
||||
// 初始化客户数据
|
||||
var customers = new List<Custom>
|
||||
{
|
||||
new Custom { Id = 1, Name = "Customer 1" },
|
||||
new Custom { Id = 2, Name = "Customer 2" },
|
||||
new Custom { Id = 3, Name = "Customer 3" },
|
||||
};
|
||||
|
||||
// Get database connection
|
||||
// 获取数据库连接
|
||||
var db = DbHelper.GetNewDb();
|
||||
|
||||
// Initialize database tables and truncate data
|
||||
// 初始化数据库表并清空数据
|
||||
db.CodeFirst.InitTables<Custom, OrderDetail, Order>();
|
||||
db.DbMaintenance.TruncateTable<Custom, OrderDetail, Order>();
|
||||
|
||||
// Insert data into tables
|
||||
// 向表中插入数据
|
||||
db.Insertable(orders).ExecuteCommand();
|
||||
db.Insertable(orderDetails).ExecuteCommand();
|
||||
db.Insertable(customers).ExecuteCommand();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 订单实体类。
|
||||
/// Order entity class.
|
||||
/// </summary>
|
||||
[SqlSugar.SugarTable("Order04")]
|
||||
public class Order
|
||||
{
|
||||
[SqlSugar.SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public int CustomId { get; set; }
|
||||
// 其他订单相关属性...
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 订单详情实体类。
|
||||
/// Order detail entity class.
|
||||
/// </summary>
|
||||
[SqlSugar.SugarTable("OrderDetail04")]
|
||||
public class OrderDetail
|
||||
{
|
||||
[SqlSugar.SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
public int OrderId { get; set; }
|
||||
// 其他订单详情相关属性...
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 客户实体类。
|
||||
/// Customer entity class.
|
||||
/// </summary>
|
||||
[SqlSugar.SugarTable("Custom04")]
|
||||
public class Custom
|
||||
{
|
||||
[SqlSugar.SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
// 其他客户相关属性...
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 类1实体类。
|
||||
/// Class1 entity class.
|
||||
/// </summary>
|
||||
public class ViewOrder2
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string CustomName { get; set; }
|
||||
// 其他类1相关属性...
|
||||
}
|
||||
}
|
||||
}
|
||||
68
Src/Asp.NetCore2/DuckDBTest/4_Subquery.cs
Normal file
68
Src/Asp.NetCore2/DuckDBTest/4_Subquery.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using SqlSugar;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OrmTest
|
||||
{
|
||||
public class _4_Subquery
|
||||
{
|
||||
public static void Init()
|
||||
{
|
||||
|
||||
var db = DbHelper.GetNewDb();
|
||||
|
||||
db.CodeFirst.InitTables<Student, School>();
|
||||
db.DbMaintenance.TruncateTable<Student, School>();
|
||||
|
||||
db.Insertable(new Student() { Id = 1, SchoolId = 1 }).ExecuteCommand();
|
||||
db.Insertable(new School() { Id = 1, Name = "Harvard School" }).ExecuteCommand();
|
||||
db.Insertable(new Student() { Id = 2, SchoolId = 2 }).ExecuteCommand();
|
||||
db.Insertable(new School() { Id = 2, Name = "haha School" }).ExecuteCommand();
|
||||
|
||||
//subquery select
|
||||
var result = db.Queryable<Student>()
|
||||
.Select(st => new
|
||||
{
|
||||
SchoolName = SqlFunc.Subqueryable<School>().Where(s => s.Id == st.SchoolId).Select(s => s.Name),
|
||||
MaxSchoolId = SqlFunc.Subqueryable<School>().Where(s => s.Id == st.SchoolId).Select(s => SqlFunc.AggregateMax(s.Id)),
|
||||
MaxSchoolId2 = SqlFunc.Subqueryable<School>().Where(s => s.Id == st.SchoolId).Max(s => s.Id),
|
||||
})
|
||||
.ToList();
|
||||
|
||||
//Exists:
|
||||
//SELECT [Id],[SchoolId] FROM [Student0402] [it] WHERE (EXISTS ( SELECT * FROM [School0402] [s] WHERE ( [Id] = [it].[SchoolId] ) ))
|
||||
var result2 = db.Queryable<Student>()
|
||||
.Where(it => SqlFunc.Subqueryable<School>().Where(s => s.Id == it.SchoolId).Any())
|
||||
.ToList();
|
||||
|
||||
//In:
|
||||
//SELECT [Id],[SchoolId] FROM [Student0402] [it] WHERE [Id] in (SELECT [Id] FROM [School0402] [s] GROUP BY [Id])
|
||||
var result3 = db.Queryable<Student>()
|
||||
.Where(it => it.Id == SqlFunc.Subqueryable<School>().GroupBy(s => s.Id).Select(s => s.Id))
|
||||
.ToList();
|
||||
|
||||
//Equal:
|
||||
//SELECT [Id],[SchoolId] FROM [Student0402] [it] WHERE ( [Id] =(SELECT TOP 1 [s].[Id] FROM [School0402] [s] ))
|
||||
var result4 = db.Queryable<Student>()
|
||||
.Where(it => it.Id == SqlFunc.Subqueryable<School>().Select(s => s.Id))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
[SugarTable("Student0402")]
|
||||
public class Student
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int SchoolId { get; set; }
|
||||
}
|
||||
[SugarTable("School0402")]
|
||||
public class School
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
112
Src/Asp.NetCore2/DuckDBTest/5_PageQuery.cs
Normal file
112
Src/Asp.NetCore2/DuckDBTest/5_PageQuery.cs
Normal file
@@ -0,0 +1,112 @@
|
||||
using OrmTest;
|
||||
using SqlSugar;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public class _5_PageQuery
|
||||
{
|
||||
public static void Init()
|
||||
{
|
||||
|
||||
int pagenumber = 1;
|
||||
int pageSize = 20;
|
||||
int totalCount = 0;
|
||||
|
||||
SqlSugarClient db = DbHelper.GetNewDb();
|
||||
|
||||
//建表
|
||||
//Create table
|
||||
AddTestData(db);
|
||||
|
||||
// 同步分页方法
|
||||
// Synchronous pagination method
|
||||
SyncPagination(db, pagenumber, pageSize, ref totalCount);
|
||||
|
||||
// 异步分页方法
|
||||
// Asynchronous pagination method
|
||||
AsyncPagination(db, pagenumber, pageSize) .GetAwaiter() .GetResult();
|
||||
}
|
||||
|
||||
public static void AddTestData(SqlSugarClient db)
|
||||
{
|
||||
|
||||
//建表
|
||||
//Create table
|
||||
db.CodeFirst.InitTables<School, Student>();
|
||||
|
||||
// 添加学校数据
|
||||
// Add school data
|
||||
var school1 = new School { Name = "School A" };
|
||||
var school2 = new School { Name = "School B" };
|
||||
db.Insertable(school1).ExecuteCommand();
|
||||
db.Insertable(school2).ExecuteCommand();
|
||||
|
||||
// 添加学生数据
|
||||
// Add student data
|
||||
var student1 = new Student { SchoolId = school1.Id, Name = "John", CreateTime = DateTime.Now };
|
||||
var student2 = new Student { SchoolId = school1.Id, Name = "Alice", CreateTime = DateTime.Now };
|
||||
|
||||
db.Insertable(student1).ExecuteCommand();
|
||||
db.Insertable(student2).ExecuteCommand();
|
||||
|
||||
Console.WriteLine("Test data added successfully.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 同步分页示例
|
||||
/// Synchronous pagination example
|
||||
/// </summary>
|
||||
/// <param name="db">数据库连接对象 Database connection object</param>
|
||||
/// <param name="pagenumber">页码 Page number</param>
|
||||
/// <param name="pageSize">每页大小 Page size</param>
|
||||
/// <param name="totalCount">总记录数 Total record count</param>
|
||||
public static void SyncPagination(SqlSugarClient db, int pagenumber, int pageSize, ref int totalCount)
|
||||
{
|
||||
// 同步单表分页
|
||||
// Synchronous pagination for a single table
|
||||
var page = db.Queryable<Student>().ToPageList(pagenumber, pageSize, ref totalCount);
|
||||
|
||||
// 同步多表分页
|
||||
// Synchronous pagination for multiple tables
|
||||
var list = db.Queryable<Student>().LeftJoin<School>((st, sc) => st.SchoolId == sc.Id)
|
||||
.Select((st, sc) => new { Id = st.Id, Name = st.Name, SchoolName = sc.Name })
|
||||
.ToPageList(pagenumber, pageSize, ref totalCount);
|
||||
|
||||
// offset分页
|
||||
// offset pagination
|
||||
var sqlServerPage = db.Queryable<Student>().ToOffsetPage(pagenumber, pageSize);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步分页示例
|
||||
/// Asynchronous pagination example
|
||||
/// </summary>
|
||||
/// <param name="db">数据库连接对象 Database connection object</param>
|
||||
/// <param name="pagenumber">页码 Page number</param>
|
||||
/// <param name="pageSize">每页大小 Page size</param>
|
||||
public static async Task AsyncPagination(SqlSugarClient db, int pagenumber, int pageSize)
|
||||
{
|
||||
RefAsync<int> total = 0;
|
||||
// 异步分页
|
||||
// Asynchronous pagination
|
||||
var orders = await db.Queryable<Student>().ToPageListAsync(pagenumber, pageSize, total);
|
||||
}
|
||||
[SugarTable("Student05")]
|
||||
public class Student
|
||||
{
|
||||
[SugarColumn(IsIdentity =true,IsPrimaryKey =true)]
|
||||
public int Id { get; set; }
|
||||
public int SchoolId { get; set; }
|
||||
public string Name { get; set; }
|
||||
public DateTime CreateTime { get; set; }
|
||||
}
|
||||
[SugarTable("School05")]
|
||||
public class School
|
||||
{
|
||||
[SugarColumn(IsIdentity = true, IsPrimaryKey = true)]
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
||||
268
Src/Asp.NetCore2/DuckDBTest/6_NavigationPropertyQuery.cs
Normal file
268
Src/Asp.NetCore2/DuckDBTest/6_NavigationPropertyQuery.cs
Normal file
@@ -0,0 +1,268 @@
|
||||
using SqlSugar;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OrmTest
|
||||
{
|
||||
internal class _6_NavQuery
|
||||
{
|
||||
/// <summary>
|
||||
/// Initialize navigation query examples.
|
||||
/// 初始化导航查询示例。
|
||||
/// </summary>
|
||||
public static void Init()
|
||||
{
|
||||
var db = DbHelper.GetNewDb();
|
||||
|
||||
// Initialize database table structures.
|
||||
// 初始化数据库表结构。
|
||||
InitializeDatabase(db);
|
||||
|
||||
// One-to-One navigation query test.
|
||||
// 一对一导航查询测试。
|
||||
OneToOneTest(db);
|
||||
|
||||
// One-to-Many navigation query test.
|
||||
// 一对多导航查询测试。
|
||||
OneToManyTest(db);
|
||||
|
||||
// Many-to-Many navigation query test.
|
||||
// 多对多导航查询测试。
|
||||
ManyToManyTest(db);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test many-to-many navigation queries.
|
||||
/// 测试多对多导航查询。
|
||||
/// </summary>
|
||||
private static void ManyToManyTest(SqlSugarClient db)
|
||||
{
|
||||
// Many-to-many navigation query, query table A and include its BList.
|
||||
// 多对多导航查询,查询A表,并包含其BList。
|
||||
var list4 = db.Queryable<A>().Includes(it => it.BList).ToList();
|
||||
|
||||
// Many-to-many navigation query with filtered BList while preserving the original A records, regardless of the filter on BList.
|
||||
// 使用过滤条件的多对多导航查询,在过滤BList的同时保持A表的原始记录,不受BList过滤条件的影响。
|
||||
var list5 = db.Queryable<A>().Includes(it => it.BList.Where(s => s.BId == 1).ToList()).ToList();
|
||||
|
||||
// Many-to-many navigation query with filtered A records while preserving the original BList, regardless of the filter on A records.
|
||||
// 使用过滤条件的多对多导航查询,在过滤A表的同时保持BList的原始记录,不受A表过滤条件的影响。
|
||||
var list6 = db.Queryable<A>().Includes(it => it.BList)
|
||||
.Where(it =>it.BList.Any(s => s.BId == 1)).ToList();
|
||||
|
||||
// Many-to-many navigation query with filtered BList and filtered A records, but not preserving the original A and B records.
|
||||
// 使用过滤条件的多对多导航查询,在A表中过滤BList并过滤A记录,但不保持A表和B表的原始记录。
|
||||
var list7 = db.Queryable<A>()
|
||||
.Includes(it => it.BList.Where(s => s.BId == 1).ToList())
|
||||
.Where(it => it.BList.Any(s => s.BId == 1)).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test one-to-many navigation queries.
|
||||
/// 测试一对多导航查询。
|
||||
/// </summary>
|
||||
private static void OneToManyTest(SqlSugarClient db)
|
||||
{
|
||||
// One-to-many navigation query, query table Student and include its Books.
|
||||
// 一对多导航查询,查询Student表,并包含其Books。
|
||||
var list4 = db.Queryable<Student>().Includes(it => it.Books).ToList();
|
||||
|
||||
// One-to-many navigation query with filtered Books while preserving the original Student records, regardless of the filter on Books.
|
||||
// 使用过滤条件的一对多导航查询,在过滤Books的同时保持Student表的原始记录,不受Books过滤条件的影响。
|
||||
var list5 = db.Queryable<Student>().Includes(it => it.Books.Where(s => s.BookId == 1).ToList()).ToList();
|
||||
|
||||
// One-to-many navigation query with filtered Student records while preserving the original Books, regardless of the filter on Student records.
|
||||
// 使用过滤条件的一对多导航查询,在过滤Student表的同时保持Books的原始记录,不受Student表过滤条件的影响。
|
||||
var list6 = db.Queryable<Student>().Includes(it => it.Books)
|
||||
.Where(it => it.Books.Any(s => s.BookId == 1)).ToList();
|
||||
|
||||
// One-to-many navigation query with filtered Books and filtered Student records, but not preserving the original Student and Books records.
|
||||
// 使用过滤条件的一对多导航查询,在Student表中过滤Books并过滤Student记录,但不保持Student表和Books表的原始记录。
|
||||
var list7 = db.Queryable<Student>()
|
||||
.Includes(it => it.Books.Where(s => s.BookId == 1).ToList())
|
||||
.Where(it => it.Books.Any(s => s.BookId == 1)).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test one-to-one navigation queries.
|
||||
/// 测试一对一导航查询。
|
||||
/// </summary>
|
||||
private static void OneToOneTest(SqlSugarClient db)
|
||||
{
|
||||
// One-to-one navigation query with condition, query table Student and include its associated School with specific SchoolId.
|
||||
// 带条件的一对一导航查询,查询Student表,并包含其关联的School表,条件为特定的SchoolId。
|
||||
var list = db.Queryable<Student>()
|
||||
.Where(it => it.School.SchoolId == 1)
|
||||
.ToList();
|
||||
|
||||
// Inner join navigation query, query table Student and include its associated School.
|
||||
// 内连接导航查询,查询Student表,并包含其关联的School表。
|
||||
var list2 = db.Queryable<Student>().IncludeInnerJoin(it => it.School)
|
||||
.ToList();
|
||||
|
||||
// Includes navigation query, query table Student and include its associated School.
|
||||
// 包含导航查询,查询Student表,并包含其关联的School表。
|
||||
var list3 = db.Queryable<Student>().Includes(it => it.School).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize database tables and insert sample data for navigation query examples.
|
||||
/// 初始化导航查询示例的数据库表并插入示例数据。
|
||||
/// </summary>
|
||||
private static void InitializeDatabase(SqlSugarClient db)
|
||||
{
|
||||
// Initialize and truncate tables for Student, School, and Book entities.
|
||||
// 初始化并清空Student、School和Book表。
|
||||
db.CodeFirst.InitTables<Student, School, Book>();
|
||||
db.DbMaintenance.TruncateTable<Student, School, Book>();
|
||||
|
||||
// Sample data for Student, School, and Book entities.
|
||||
// Student、School和Book表的示例数据。
|
||||
var students = new List<Student>
|
||||
{
|
||||
new Student
|
||||
{
|
||||
Name = "Student 1",
|
||||
SexCode = "M",
|
||||
School = new School { SchoolName = "School 1" },
|
||||
Books = new List<Book>
|
||||
{
|
||||
new Book { Name = "Book 1" },
|
||||
new Book { Name = "Book 2" }
|
||||
}
|
||||
},
|
||||
new Student
|
||||
{
|
||||
Name = "Student 2",
|
||||
SexCode = "F",
|
||||
School = new School { SchoolName = "School 2" },
|
||||
Books = new List<Book>
|
||||
{
|
||||
new Book { Name = "Book 3" }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Insert sample data for Student, School, and Book entities using navigation properties.
|
||||
// 使用导航属性插入Student、School和Book表的示例数据。
|
||||
db.InsertNav(students)
|
||||
.Include(it => it.School)
|
||||
.Include(it => it.Books).ExecuteCommand();
|
||||
|
||||
// Initialize and truncate tables for A, B, and ABMapping entities.
|
||||
// 初始化并清空A、B和ABMapping表。
|
||||
db.CodeFirst.InitTables<A, B, ABMapping>();
|
||||
db.DbMaintenance.TruncateTable<A, B, ABMapping>();
|
||||
|
||||
// Sample data for A, B, and ABMapping entities.
|
||||
// A、B和ABMapping表的示例数据。
|
||||
List<A> a1 = new List<A> { new A() { Name = "A1" }, new A() { Name = "A2" } };
|
||||
B b1 = new B { Name = "B1" };
|
||||
B b2 = new B { Name = "B2" };
|
||||
a1[0].BList = new List<B> { b1, b2 };
|
||||
|
||||
// Insert sample data for A, B, and ABMapping entities using navigation properties.
|
||||
// 使用导航属性插入A、B和ABMapping表的示例数据。
|
||||
db.InsertNav(a1).Include(x => x.BList).ExecuteCommand();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Student entity representing the Student table in the database.
|
||||
/// 表示数据库中Student表的Student实体类。
|
||||
/// </summary>
|
||||
[SugarTable("Student06")]
|
||||
public class Student
|
||||
{
|
||||
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int StudentId { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string SexCode { get; set; }
|
||||
public int SchoolId { get; set; }
|
||||
|
||||
// One-to-One navigation property to School entity.
|
||||
// 与School实体的一对一导航属性。
|
||||
[Navigate(NavigateType.OneToOne, nameof(SchoolId))]
|
||||
public School School { get; set; }
|
||||
|
||||
// One-to-Many navigation property to Book entities.
|
||||
// 与Book实体的一对多导航属性。
|
||||
[Navigate(NavigateType.OneToMany, nameof(Book.StudentId))]
|
||||
public List<Book> Books { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// School entity representing the School table in the database.
|
||||
/// 表示数据库中School表的School实体类。
|
||||
/// </summary>
|
||||
[SugarTable("School06")]
|
||||
public class School
|
||||
{
|
||||
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int SchoolId { get; set; }
|
||||
public string SchoolName { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Book entity representing the Book table in the database.
|
||||
/// 表示数据库中Book表的Book实体类。
|
||||
/// </summary>
|
||||
[SugarTable("Book06")]
|
||||
public class Book
|
||||
{
|
||||
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int BookId { get; set; }
|
||||
public string Name { get; set; }
|
||||
public int StudentId { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A entity representing the A table in the database for many-to-many relationship.
|
||||
/// 表示多对多关系中数据库中A表的A实体类。
|
||||
/// </summary>
|
||||
[SugarTable("A06")]
|
||||
public class A
|
||||
{
|
||||
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int AId { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
||||
// Many-to-Many navigation property to B entities using ABMapping table.
|
||||
// 与B实体的多对多导航属性,使用ABMapping表。
|
||||
[Navigate(typeof(ABMapping), nameof(ABMapping.AId), nameof(ABMapping.BId))]
|
||||
public List<B> BList { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// B entity representing the B table in the database for many-to-many relationship.
|
||||
/// 表示多对多关系中数据库中B表的B实体类。
|
||||
/// </summary>
|
||||
[SugarTable("B06")]
|
||||
public class B
|
||||
{
|
||||
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int BId { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
||||
// Many-to-Many navigation property to A entities using ABMapping table.
|
||||
// 与A实体的多对多导航属性,使用ABMapping表。
|
||||
[Navigate(typeof(ABMapping), nameof(ABMapping.BId), nameof(ABMapping.AId))]
|
||||
public List<A> AList { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ABMapping entity representing the intermediate table for many-to-many relationship between A and B entities.
|
||||
/// 表示A和B实体之间多对多关系的中间表的ABMapping实体类。
|
||||
/// </summary>
|
||||
[SugarTable("ABMapping06")]
|
||||
public class ABMapping
|
||||
{
|
||||
[SugarColumn(IsPrimaryKey = true)]
|
||||
public int AId { get; set; }
|
||||
[SugarColumn(IsPrimaryKey = true)]
|
||||
public int BId { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
74
Src/Asp.NetCore2/DuckDBTest/7_GroupQuery.cs
Normal file
74
Src/Asp.NetCore2/DuckDBTest/7_GroupQuery.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using SqlSugar;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OrmTest
|
||||
{
|
||||
internal class _7_GroupQuery
|
||||
{
|
||||
public static void Init()
|
||||
{
|
||||
var db = DbHelper.GetNewDb();
|
||||
List<Student> students = new List<Student>
|
||||
{
|
||||
new Student { Id = 1, Name = "Alice", Age = 20 },
|
||||
new Student { Id = 2, Name = "Bob", Age = 22 },
|
||||
new Student { Id = 3, Name = "Alice", Age = 21 },
|
||||
new Student { Id = 4, Name = "Charlie", Age = 19 },
|
||||
new Student { Id = 5, Name = "Bob", Age = 20 }
|
||||
};
|
||||
|
||||
// 初始化数据库表结构,如果表不存在则创建 (Initialize database table structure; create if not exists)
|
||||
db.CodeFirst.InitTables<Student>();
|
||||
|
||||
// 清空指定表中的所有数据 (Truncate all data in the specified table)
|
||||
db.DbMaintenance.TruncateTable<Student>();
|
||||
|
||||
//插入记录(Insert datas)
|
||||
db.Insertable(students).ExecuteCommand();
|
||||
|
||||
// 分组查询示例 (Grouping Query Example)
|
||||
var groupedStudents = db.Queryable<Student>()
|
||||
.GroupBy(s => s.Name)
|
||||
.Select(g => new
|
||||
{
|
||||
Name = g.Name, // 学生姓名 (Student Name)
|
||||
Count = SqlFunc.AggregateCount(g.Id), // 学生数量 (Count of Students)
|
||||
AverageAge = SqlFunc.AggregateAvg(g.Age), // 平均年龄 (Average Age)
|
||||
MaxAge = SqlFunc.AggregateMax(g.Age), // 最大年龄 (Maximum Age)
|
||||
MinAge = SqlFunc.AggregateMin(g.Age) // 最小年龄 (Minimum Age)
|
||||
})
|
||||
.ToList();
|
||||
|
||||
|
||||
// 去重查询示例 (Distinct Query Example)
|
||||
var distinctNames = students.Select(s => s.Name).Distinct().ToList();
|
||||
|
||||
|
||||
// 分组取第一条记录示例 (Group First Record Example)
|
||||
var groupFirstRecord = db.Queryable<Student>()
|
||||
.Select(g => new
|
||||
{
|
||||
index = SqlFunc.RowNumber(SqlFunc.Desc(g.Id), g.Name),
|
||||
Id = g.Id,
|
||||
Name = g.Name,
|
||||
Age =g.Age
|
||||
})
|
||||
.MergeTable()
|
||||
.Where(it => it.index == 1)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
[SqlSugar.SugarTable("Student07")]
|
||||
public class Student
|
||||
{
|
||||
[SqlSugar.SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; } // 学生ID (Student ID)
|
||||
public string Name { get; set; } // 学生姓名 (Student Name)
|
||||
public int Age { get; set; } // 学生年龄 (Student Age)
|
||||
}
|
||||
}
|
||||
}
|
||||
66
Src/Asp.NetCore2/DuckDBTest/8_Insert.cs
Normal file
66
Src/Asp.NetCore2/DuckDBTest/8_Insert.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
using SqlSugar;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OrmTest
|
||||
{
|
||||
internal class _8_Insert
|
||||
{
|
||||
public static void Init()
|
||||
{
|
||||
var db = DbHelper.GetNewDb();
|
||||
|
||||
// 初始化实体表格(Initialize entity tables)
|
||||
db.CodeFirst.InitTables<StudentWithIdentity, StudentWithSnowflake>();
|
||||
|
||||
// Use Case 1: 返回插入行数(Return the number of inserted rows)
|
||||
var rowCount = db.Insertable(new StudentWithIdentity() { Name = "name" }).ExecuteCommand();
|
||||
|
||||
// Use Case 2: 插入数据并返回自增列(Insert data and return the auto-incremented column)
|
||||
var identity = db.Insertable(new StudentWithIdentity() { Name = "name2" }).ExecuteReturnIdentity();
|
||||
|
||||
// Use Case 3: 返回雪花ID(Return the snowflake ID)
|
||||
var snowflakeId = db.Insertable(new StudentWithSnowflake() { Name = "name" }).ExecuteReturnSnowflakeId();
|
||||
|
||||
// Use Case 4: 强制设置表名别名(Forcefully set table name alias)
|
||||
db.Insertable(new StudentWithIdentity() { Name = "name2" }).AS("StudentWithIdentity").ExecuteCommand();
|
||||
|
||||
// Use Case 5: 批量插入实体(非参数化插入)(Batch insert entities (non-parameterized))
|
||||
var list = db.Queryable<StudentWithIdentity>().Take(2).ToList();
|
||||
db.Insertable(list).ExecuteCommand();
|
||||
db.Insertable(list).PageSize(1000).ExecuteCommand();
|
||||
|
||||
// Use Case 6: 参数化内部分页插入(Parameterized internal pagination insert)
|
||||
db.Insertable(list).UseParameter().ExecuteCommand();
|
||||
|
||||
// Use Case 7: 大数据写入(示例代码,请根据实际情况调整)(Bulk data insertion - Example code, adjust based on actual scenario)
|
||||
var listLong = new List<StudentWithSnowflake>() {
|
||||
new StudentWithSnowflake() { Name = "name",Id=SnowFlakeSingle.Instance.NextId() },
|
||||
new StudentWithSnowflake() { Name = "name",Id=SnowFlakeSingle.Instance.NextId()}
|
||||
};
|
||||
db.Fastest<StudentWithSnowflake>().BulkCopy(listLong);
|
||||
}
|
||||
|
||||
// 实体类:带自增主键(Entity class: With auto-increment primary key)
|
||||
[SugarTable("StudentWithIdentity08")]
|
||||
public class StudentWithIdentity
|
||||
{
|
||||
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
// 实体类:带雪花主键(Entity class: With snowflake primary key)
|
||||
[SugarTable("StudentWithSnowflake08")]
|
||||
public class StudentWithSnowflake
|
||||
{
|
||||
[SugarColumn(IsPrimaryKey = true)]
|
||||
public long Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
88
Src/Asp.NetCore2/DuckDBTest/9_Update.cs
Normal file
88
Src/Asp.NetCore2/DuckDBTest/9_Update.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
using SqlSugar;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static OrmTest._8_Insert;
|
||||
|
||||
namespace OrmTest
|
||||
{
|
||||
internal class _9_Update
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始化更新方法(Initialize update methods)
|
||||
/// </summary>
|
||||
internal static void Init()
|
||||
{
|
||||
var db = DbHelper.GetNewDb();
|
||||
|
||||
// 初始化实体表格(Initialize entity tables)
|
||||
db.CodeFirst.InitTables<StudentWithSnowflake>();
|
||||
|
||||
// 创建一个需要更新的实体对象(Create an entity object to be updated)
|
||||
var updateObj = new StudentWithSnowflake() { Id = 1, Name = "order1" };
|
||||
|
||||
// 创建需要批量更新的实体对象列表(Create a list of entity objects to be updated in bulk)
|
||||
var updateObjs = new List<StudentWithSnowflake> {
|
||||
new StudentWithSnowflake() { Id = 11, Name = "order11", Date=DateTime.Now },
|
||||
new StudentWithSnowflake() { Id = 12, Name = "order12", Date=DateTime.Now }
|
||||
};
|
||||
|
||||
/***************************根据实体更新 (Update based on entity)***************************/
|
||||
|
||||
// 更新单个实体对象(Update a single entity object)
|
||||
var result = db.Updateable(updateObj).ExecuteCommand();
|
||||
|
||||
// 批量更新实体对象列表(Update a list of entity objects in bulk)
|
||||
var result20 = db.Updateable(updateObjs).ExecuteCommand();
|
||||
var result21 = db.Updateable(updateObjs).PageSize(500).ExecuteCommand();
|
||||
|
||||
// 更新实体对象,忽略指定列(Update entity object, ignoring specific columns)
|
||||
var result3 = db.Updateable(updateObj).IgnoreColumns(it => new { it.Remark }).ExecuteCommand();
|
||||
|
||||
// 更新实体对象的指定列(Update specific columns of the entity object)
|
||||
var result4 = db.Updateable(updateObj).UpdateColumns(it => new { it.Name, it.Date }).ExecuteCommand();
|
||||
|
||||
// 如果没有主键,按照指定列更新实体对象(If there is no primary key, update entity object based on specified columns)
|
||||
var result5 = db.Updateable(updateObj).WhereColumns(it => new { it.Id }).ExecuteCommand();
|
||||
|
||||
// 如果字段值为NULL,不进行更新(Do not update columns with NULL values)
|
||||
var result6 = db.Updateable(updateObj).IgnoreNullColumns().ExecuteCommand();
|
||||
|
||||
// 忽略为NULL和默认值的列进行更新(Ignore columns with NULL and default values during update)
|
||||
var result7 = db.Updateable(updateObj)
|
||||
.IgnoreColumns(ignoreAllNullColumns: true, ignoreAllDefaultValue:true)
|
||||
.ExecuteCommand();
|
||||
|
||||
// 使用最快的方式批量更新实体对象列表(Bulk update a list of entity objects using the fastest method)
|
||||
var result8 = db.Fastest<StudentWithSnowflake>().BulkUpdate(updateObjs);
|
||||
|
||||
/***************************表达式更新 (Expression Update)***************************/
|
||||
|
||||
// 使用表达式更新实体对象的指定列(Update specific columns of the entity object using expressions)
|
||||
var result71 = db.Updateable<StudentWithSnowflake>()
|
||||
.SetColumns(it => new StudentWithSnowflake() { Name = "a", Date = DateTime.Now })
|
||||
.Where(it => it.Id == 11)
|
||||
.ExecuteCommand();
|
||||
|
||||
// 使用表达式更新实体对象的指定列(Update specific columns of the entity object using expressions)
|
||||
var result81 = db.Updateable<StudentWithSnowflake>()
|
||||
.SetColumns(it => it.Name == "Name" + "1")
|
||||
.Where(it => it.Id == 1)
|
||||
.ExecuteCommand();
|
||||
}
|
||||
|
||||
// 实体类:带雪花主键(Entity class: With snowflake primary key)
|
||||
[SugarTable("StudentWithSnowflake09")]
|
||||
public class StudentWithSnowflake
|
||||
{
|
||||
[SugarColumn(IsPrimaryKey = true)]
|
||||
public long Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public DateTime Date { get; set; }
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public string Remark { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
14
Src/Asp.NetCore2/DuckDBTest/DuckDBTest.csproj
Normal file
14
Src/Asp.NetCore2/DuckDBTest/DuckDBTest.csproj
Normal file
@@ -0,0 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<OutputType>Exe</OutputType>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SqlSugar.DuckDBCore\SqlSugar.DuckDBCore.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
40
Src/Asp.NetCore2/DuckDBTest/Program.cs
Normal file
40
Src/Asp.NetCore2/DuckDBTest/Program.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using SqlSugar;
|
||||
|
||||
Console.Read();
|
||||
/// <summary>
|
||||
/// Helper class for database operations
|
||||
/// 数据库操作的辅助类
|
||||
/// </summary>
|
||||
public class DbHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Database connection string
|
||||
/// 数据库连接字符串
|
||||
/// </summary>
|
||||
public readonly static string Connection = "DataSource = train_services.db";
|
||||
|
||||
/// <summary>
|
||||
/// Get a new SqlSugarClient instance with specific configurations
|
||||
/// 获取具有特定配置的新 SqlSugarClient 实例
|
||||
/// </summary>
|
||||
/// <returns>SqlSugarClient instance</returns>
|
||||
public static SqlSugarClient GetNewDb()
|
||||
{
|
||||
var db = new SqlSugarClient(new ConnectionConfig()
|
||||
{
|
||||
IsAutoCloseConnection = true,
|
||||
DbType = DbType.DuckDB,
|
||||
ConnectionString = Connection,
|
||||
LanguageType = LanguageType.Default//Set language
|
||||
|
||||
},
|
||||
it => {
|
||||
// Logging SQL statements and parameters before execution
|
||||
// 在执行前记录 SQL 语句和参数
|
||||
it.Aop.OnLogExecuting = (sql, para) =>
|
||||
{
|
||||
Console.WriteLine(UtilMethods.GetNativeSql(sql, para));
|
||||
};
|
||||
});
|
||||
return db;
|
||||
}
|
||||
186
Src/Asp.NetCore2/DuckDBTest/a1_Delete.cs
Normal file
186
Src/Asp.NetCore2/DuckDBTest/a1_Delete.cs
Normal file
@@ -0,0 +1,186 @@
|
||||
using SqlSugar;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace OrmTest
|
||||
{
|
||||
internal class _a1_Delete
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始化删除操作的示例方法。
|
||||
/// Initializes example methods for delete operations.
|
||||
/// </summary>
|
||||
internal static void Init()
|
||||
{
|
||||
// 获取新的数据库连接对象
|
||||
// Get a new database connection object
|
||||
var db = DbHelper.GetNewDb();
|
||||
|
||||
db.CodeFirst.InitTables<Student, Order>();
|
||||
|
||||
// 调用各个删除操作的示例方法
|
||||
// Calling example methods for various delete operations
|
||||
DeleteSingleEntity(db);
|
||||
|
||||
// 批量删除实体的示例方法
|
||||
// Example method for deleting entities in batch
|
||||
DeleteBatchEntities(db);
|
||||
|
||||
// 批量删除并分页的示例方法
|
||||
// Example method for deleting entities in batch with paging
|
||||
DeleteBatchEntitiesWithPaging(db);
|
||||
|
||||
// 调用无主键实体删除的示例方法
|
||||
// Calling example method for deleting entities without primary key
|
||||
DeleteEntitiesWithoutPrimaryKey(db);
|
||||
|
||||
// 调用根据主键删除实体的示例方法
|
||||
// Calling example method for deleting entity by primary key
|
||||
DeleteEntityByPrimaryKey(1, db);
|
||||
|
||||
// 调用根据主键数组批量删除实体的示例方法
|
||||
// Calling example method for deleting entities by primary key array
|
||||
DeleteEntitiesByPrimaryKeyArray(db);
|
||||
|
||||
// 调用根据表达式删除实体的示例方法
|
||||
// Calling example method for deleting entities by expression
|
||||
DeleteEntitiesByExpression(db);
|
||||
|
||||
// 调用联表删除实体的示例方法
|
||||
// Calling example method for deleting entities with join
|
||||
DeleteEntitiesWithJoin(db);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除单个实体的示例方法。
|
||||
/// Example method for deleting a single entity.
|
||||
/// </summary>
|
||||
internal static void DeleteSingleEntity(ISqlSugarClient db)
|
||||
{
|
||||
// 删除指定 Id 的学生实体
|
||||
// Delete the student entity with the specified Id
|
||||
db.Deleteable<Student>(new Student() { Id = 1 }).ExecuteCommand();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 批量删除实体的示例方法。
|
||||
/// Example method for deleting entities in batch.
|
||||
/// </summary>
|
||||
internal static void DeleteBatchEntities(ISqlSugarClient db)
|
||||
{
|
||||
// 创建学生实体列表
|
||||
// Create a list of student entities
|
||||
List<Student> list = new List<Student>()
|
||||
{
|
||||
new Student() { Id = 1 }
|
||||
};
|
||||
|
||||
// 批量删除学生实体
|
||||
// Delete student entities in batch
|
||||
db.Deleteable<Student>(list).ExecuteCommand();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 批量删除并分页的示例方法。
|
||||
/// Example method for deleting entities in batch with paging.
|
||||
/// </summary>
|
||||
internal static void DeleteBatchEntitiesWithPaging(ISqlSugarClient db)
|
||||
{
|
||||
// 创建订单实体列表
|
||||
// Create a list of order entities
|
||||
List<Order> list = new List<Order>();
|
||||
|
||||
// 批量删除订单实体并分页
|
||||
// Delete order entities in batch with paging
|
||||
db.Deleteable<Order>(list).PageSize(500).ExecuteCommand();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 无主键实体删除的示例方法。
|
||||
/// Example method for deleting entities without primary key.
|
||||
/// </summary>
|
||||
internal static void DeleteEntitiesWithoutPrimaryKey( ISqlSugarClient db)
|
||||
{
|
||||
List<Order> orders = new List<Order>()
|
||||
{
|
||||
new Order() { Id = 1 },
|
||||
new Order() { Id = 2 }
|
||||
};
|
||||
|
||||
// 根据指定的实体列表的 Id 列进行删除
|
||||
// Delete entities based on the Id column of the specified entity list
|
||||
db.Deleteable<Order>().WhereColumns(orders, it => new { it.Id }).ExecuteCommand();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据主键删除实体的示例方法。
|
||||
/// Example method for deleting an entity by primary key.
|
||||
/// </summary>
|
||||
internal static void DeleteEntityByPrimaryKey(int id, ISqlSugarClient db)
|
||||
{
|
||||
// 根据指定的 Id 删除学生实体
|
||||
// Delete the student entity with the specified Id
|
||||
db.Deleteable<Student>().In(id).ExecuteCommand();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据主键数组批量删除实体的示例方法。
|
||||
/// Example method for deleting entities by primary key array.
|
||||
/// </summary>
|
||||
internal static void DeleteEntitiesByPrimaryKeyArray(ISqlSugarClient db)
|
||||
{
|
||||
// 定义主键数组
|
||||
// Define an array of primary keys
|
||||
int[] ids = { 1, 2 };
|
||||
|
||||
// 根据指定的 Id 数组批量删除学生实体
|
||||
// Delete student entities in batch based on the specified Id array
|
||||
db.Deleteable<Student>().In(ids).ExecuteCommand();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据表达式删除实体的示例方法。
|
||||
/// Example method for deleting entities by expression.
|
||||
/// </summary>
|
||||
internal static void DeleteEntitiesByExpression(ISqlSugarClient db)
|
||||
{
|
||||
// 根据指定的表达式删除学生实体
|
||||
// Delete the student entity based on the specified expression
|
||||
db.Deleteable<Student>().Where(it => it.Id == 1).ExecuteCommand();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 联表删除实体的示例方法。
|
||||
/// Example method for deleting entities with join.
|
||||
/// </summary>
|
||||
internal static void DeleteEntitiesWithJoin(ISqlSugarClient db)
|
||||
{
|
||||
// 联表删除学生实体
|
||||
// Delete student entities with join
|
||||
db.Deleteable<Student>()
|
||||
.Where(p => SqlFunc.Subqueryable<Order>().Where(s => s.Id == p.SchoolId).Any())
|
||||
.ExecuteCommand();
|
||||
}
|
||||
|
||||
[SugarTable("Students_a1")]
|
||||
public class Student
|
||||
{
|
||||
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)] // 主键
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public int SchoolId { get; set; }
|
||||
}
|
||||
|
||||
[SugarTable("Orders_a2")]
|
||||
public class Order
|
||||
{
|
||||
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)] // 主键
|
||||
public int Id { get; set; }
|
||||
|
||||
public string OrderNumber { get; set; }
|
||||
|
||||
public decimal Amount { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
74
Src/Asp.NetCore2/DuckDBTest/a2_Sql.cs
Normal file
74
Src/Asp.NetCore2/DuckDBTest/a2_Sql.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using SqlSugar;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace OrmTest
|
||||
{
|
||||
internal class _a2_Sql
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始化 SQL 操作的示例方法。
|
||||
/// Initializes example methods for SQL operations.
|
||||
/// </summary>
|
||||
internal static void Init()
|
||||
{
|
||||
// 获取新的数据库连接对象
|
||||
// Get a new database connection object
|
||||
var db = DbHelper.GetNewDb();
|
||||
|
||||
// CodeFirst 初始化 ClassA 表
|
||||
// CodeFirst initializes the ClassA table
|
||||
db.CodeFirst.InitTables<ClassA>();
|
||||
db.Insertable(new ClassA() { Name = Guid.NewGuid().ToString("N") }).ExecuteCommand();
|
||||
|
||||
// 1. 无参数查询 DataTable
|
||||
// 1. Query DataTable without parameters
|
||||
var dt1 = db.Ado.GetDataTable("SELECT * FROM Table_a2");
|
||||
|
||||
// 2. 带参数查询 DataTable(简化用法)
|
||||
// 2. Query DataTable with parameters (simplified usage)
|
||||
var dt2 = db.Ado.GetDataTable("SELECT * FROM Table_a2 WHERE id=@id AND name LIKE @name",
|
||||
new { id = 1, name = "%Jack%" });
|
||||
|
||||
// 3. 带参数查询 DataTable(复杂用法)
|
||||
// 3. Query DataTable with parameters (complex usage)
|
||||
var parameters = new List<SugarParameter>
|
||||
{
|
||||
new SugarParameter("@id", 1),
|
||||
new SugarParameter("@name", "%Jack%",System.Data.DbType.AnsiString)//DbType
|
||||
};
|
||||
var dt3 = db.Ado.GetDataTable("SELECT * FROM Table_a2 WHERE id=@id AND name LIKE @name", parameters);
|
||||
|
||||
// 4. 带参数查询 DataTable(结合用法)
|
||||
// 4. Query DataTable with parameters (combined usage)
|
||||
var dynamicParameters = db.Ado.GetParameters(new { p = 1, p2 = "A" });
|
||||
var dt4 = db.Ado.GetDataTable("SELECT * FROM Table_a2 WHERE id=@p AND name=@p2", dynamicParameters);
|
||||
|
||||
// 原生 SQL 使用实体进行查询
|
||||
// Native SQL query using an entity
|
||||
List<ClassA> entities = db.Ado.SqlQuery<ClassA>("SELECT * FROM Table_a2");
|
||||
List<ClassA> entities2 = db.Ado.SqlQuery<ClassA>("SELECT * FROM Table_a2 WHERE ID>@ID",new { ID=1});
|
||||
|
||||
// 原生 SQL 使用匿名对象进行查询
|
||||
// Native SQL query using an anonymous object
|
||||
List<dynamic> anonymousObjects = db.Ado.SqlQuery<dynamic>("SELECT * FROM Table_a2");
|
||||
|
||||
// 执行 SQL 命令(插入、更新、删除操作)
|
||||
// Execute SQL commands (insert, update, delete operations)
|
||||
db.Ado.ExecuteCommand("INSERT INTO Table_a2 (name) VALUES ( 'New Record')");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 示例实体类。
|
||||
/// Example entity class.
|
||||
/// </summary>
|
||||
[SugarTable("Table_a2")]
|
||||
public class ClassA
|
||||
{
|
||||
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
51
Src/Asp.NetCore2/DuckDBTest/a3_Merge.cs
Normal file
51
Src/Asp.NetCore2/DuckDBTest/a3_Merge.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OrmTest
|
||||
{
|
||||
internal class _a3_Merge
|
||||
{
|
||||
// 中文备注:初始化方法(用于大数据处理)
|
||||
// English Comment: Initialization method (for big data processing)
|
||||
internal static void Init()
|
||||
{
|
||||
var db = DbHelper.GetNewDb();
|
||||
//建表
|
||||
//Create table
|
||||
db.CodeFirst.InitTables<Order>();
|
||||
var list = new List<Order>() { new Order() { Name = "jack" } };
|
||||
|
||||
// 中文备注:执行插入或更新操作
|
||||
// English Comment: Perform insert or update operation
|
||||
db.Storageable(list).ExecuteCommand();
|
||||
|
||||
// 中文备注:分页执行插入或更新操作,每页1000条记录
|
||||
// English Comment: Perform insert or update operation with paging, 1000 records per page
|
||||
db.Storageable(list).PageSize(1000).ExecuteCommand();
|
||||
|
||||
// 中文备注:带异常处理的分页插入或更新操作,每页1000条记录
|
||||
// English Comment: Perform insert or update operation with exception handling and paging, 1000 records per page
|
||||
db.Storageable(list).PageSize(1000, exrows => { }).ExecuteCommand();
|
||||
|
||||
// 中文备注:使用Fastest方式批量合并数据(用于大数据处理)
|
||||
// English Comment: Merge data using Fastest method (for big data processing)
|
||||
db.Fastest<Order>().BulkMerge(list);
|
||||
|
||||
// 中文备注:分页使用Fastest方式批量合并数据,每页100000条记录(用于大数据处理)
|
||||
// English Comment: Merge data using Fastest method with paging, 100000 records per page (for big data processing)
|
||||
db.Fastest<Order>().PageSize(100000).BulkMerge(list);
|
||||
}
|
||||
|
||||
[SqlSugar.SugarTable("Order_a3")]
|
||||
public class Order
|
||||
{
|
||||
[SqlSugar.SugarColumn(IsPrimaryKey =true,IsIdentity =true)]
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
// 其他属性
|
||||
}
|
||||
}
|
||||
}
|
||||
66
Src/Asp.NetCore2/DuckDBTest/a4_SplitTable.cs
Normal file
66
Src/Asp.NetCore2/DuckDBTest/a4_SplitTable.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
using SqlSugar;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OrmTest
|
||||
{
|
||||
internal class _a4_SplitTable
|
||||
{
|
||||
// Method for initialization and testing of split tables
|
||||
// 用于初始化和测试分表的方法
|
||||
public static void Init()
|
||||
{
|
||||
// Obtain a new instance of SqlSugarClient
|
||||
// 获取 SqlSugarClient 的新实例
|
||||
SqlSugarClient db = DbHelper.GetNewDb();
|
||||
|
||||
|
||||
// Entities change the synchronization table structure
|
||||
// 实体变化同步表结构
|
||||
db.CodeFirst.SplitTables().InitTables<SplitTableDemo>();
|
||||
|
||||
// Insert records into the split table and create table
|
||||
// 向分表插入记录并创建表
|
||||
db.Insertable(new SplitTableDemo() { Name = "jack", Time = DateTime.Now }).SplitTable().ExecuteCommand();
|
||||
db.Insertable(new SplitTableDemo() { Name = "jack2", Time = DateTime.Now.AddDays(-11) }).SplitTable().ExecuteCommand();
|
||||
|
||||
// Query records from the split table within a specified date range
|
||||
// 在指定日期范围内从分表查询记录
|
||||
var list = db.Queryable<SplitTableDemo>()
|
||||
.Where(it=>it.Name!=null)
|
||||
.SplitTable(DateTime.Now.Date.AddYears(-1), DateTime.Now)
|
||||
.ToList();
|
||||
|
||||
// Update records from the split table
|
||||
// 从分表更新记录
|
||||
var updateList = list.Take(2).ToList();
|
||||
db.Updateable(updateList).SplitTable().ExecuteCommand();
|
||||
|
||||
// Delete records from the split table
|
||||
// 从分表删除记录
|
||||
db.Deleteable(updateList).SplitTable().ExecuteCommand();
|
||||
}
|
||||
|
||||
// Entity class representing the split table
|
||||
// 代表分表的实体类
|
||||
[SplitTable(SplitType.Day)] // Specify the split type as "Day"
|
||||
// 指定分表类型为“Day”
|
||||
[SqlSugar.SugarTable("SplitTableDemo_{year}{month}{day}")] // Specify the table name pattern
|
||||
// 指定表名模式
|
||||
public class SplitTableDemo
|
||||
{
|
||||
[SugarColumn(IsPrimaryKey = true)] // Specify primary key
|
||||
// 指定主键
|
||||
public Guid Pk { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
||||
[SugarColumn(IsNullable = true)]
|
||||
[SplitField] // Mark the field as a split field
|
||||
// 将字段标记为分表字段
|
||||
public DateTime Time { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
81
Src/Asp.NetCore2/DuckDBTest/a5_GridSave.cs
Normal file
81
Src/Asp.NetCore2/DuckDBTest/a5_GridSave.cs
Normal file
@@ -0,0 +1,81 @@
|
||||
using SqlSugar;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OrmTest
|
||||
{
|
||||
internal class _a5_GridSave
|
||||
{
|
||||
public static void Init()
|
||||
{
|
||||
// Get a new database connection
|
||||
// 获取一个新的数据库连接
|
||||
SqlSugarClient db = DbHelper.GetNewDb();
|
||||
|
||||
// Initialize tables using CodeFirst
|
||||
// 使用 CodeFirst 初始化表
|
||||
db.CodeFirst.InitTables<Student>();
|
||||
|
||||
// Clear table data
|
||||
// 清空表数据
|
||||
db.DbMaintenance.TruncateTable<Student>();
|
||||
|
||||
// Insert two student records
|
||||
// 插入两条学生记录
|
||||
db.Insertable(new List<Student>() {
|
||||
new Student() {Name= "jack",CreateTime=DateTime.Now},
|
||||
new Student() {Name= "tom",CreateTime=DateTime.Now}
|
||||
}).ExecuteReturnIdentity();
|
||||
|
||||
// Query all student records
|
||||
// 查询所有学生记录
|
||||
List<Student> getAll = db.Queryable<Student>().ToList();
|
||||
|
||||
|
||||
|
||||
// Enable entity tracking for the list 'getAll'
|
||||
// 启用对列表 'getAll' 的实体跟踪
|
||||
db.Tracking(getAll);
|
||||
|
||||
|
||||
|
||||
|
||||
// Remove the first record
|
||||
// 移除第一条记录
|
||||
getAll.RemoveAt(0);
|
||||
|
||||
// Modify the name of the last record
|
||||
// 修改最后一条记录的姓名
|
||||
getAll[getAll.Count - 1].Name += "_Update";
|
||||
|
||||
// Add a new record
|
||||
// 添加新记录
|
||||
getAll.Add(new Student { Name = "NewRecord" });
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Execute GridSave operation
|
||||
// 执行 GridSave 操作
|
||||
db.GridSave(getAll).ExecuteCommand();
|
||||
|
||||
// Query all students again
|
||||
// 再次查询所有学生
|
||||
var list = db.Queryable<Student>().ToList();
|
||||
}
|
||||
|
||||
// Define the entity class 定义实体类
|
||||
[SugarTable("SaveTable_a5")]
|
||||
public class Student
|
||||
{
|
||||
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public DateTime CreateTime { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
59
Src/Asp.NetCore2/DuckDBTest/a6_SqlPage.cs
Normal file
59
Src/Asp.NetCore2/DuckDBTest/a6_SqlPage.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using SqlSugar;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.ComTypes;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OrmTest
|
||||
{
|
||||
internal class _a6_SqlPage
|
||||
{
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Initializes an example method for SQL paging operations.
|
||||
/// 初始化 SQL 分页操作的示例方法。
|
||||
/// </summary>
|
||||
internal static void Init()
|
||||
{
|
||||
// Get a new database connection object
|
||||
// 获取新的数据库连接对象
|
||||
var db = DbHelper.GetNewDb();
|
||||
|
||||
// CodeFirst initializes the ClassA table
|
||||
// CodeFirst 初始化 ClassA 表
|
||||
db.CodeFirst.InitTables<ClassA>();
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
db.Insertable(new ClassA() { Name = Guid.NewGuid().ToString("N") }).ExecuteCommand();
|
||||
}
|
||||
|
||||
|
||||
// Query data using paging and get the total count
|
||||
// 使用分页查询数据,并获取总记录数
|
||||
int count = 0;
|
||||
var list = db.SqlQueryable<ClassA>("select * from Table_a6").ToPageList(1, 5, ref count);
|
||||
|
||||
|
||||
|
||||
// Asynchronously query data using paging and get the total count
|
||||
// 使用异步方式分页查询数据,并获取总记录数
|
||||
RefAsync<int> countAsync = 0;
|
||||
var listAsync = db.SqlQueryable<ClassA>("select * from Table_a6").ToPageListAsync(1, 5, countAsync).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Example entity class.
|
||||
/// 示例实体类。
|
||||
/// </summary>
|
||||
[SugarTable("Table_a6")]
|
||||
public class ClassA
|
||||
{
|
||||
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
87
Src/Asp.NetCore2/DuckDBTest/a7_JsonType.cs
Normal file
87
Src/Asp.NetCore2/DuckDBTest/a7_JsonType.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
using SqlSugar;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace OrmTest
|
||||
{
|
||||
internal class _a7_JsonType
|
||||
{
|
||||
/// <summary>
|
||||
/// Demonstrates JSON operations with SqlSugar.
|
||||
/// 展示了在 SqlSugar 中进行 JSON 操作的示例。
|
||||
/// </summary>
|
||||
internal static void Init()
|
||||
{
|
||||
// Get a new database connection object
|
||||
// 获取一个新的数据库连接对象
|
||||
var db = DbHelper.GetNewDb();
|
||||
|
||||
// Create table
|
||||
// 创建表
|
||||
db.CodeFirst.InitTables<UnitJsonTest>();
|
||||
|
||||
// Insert a record with a JSON property
|
||||
// 插入一条包含 JSON 属性的记录
|
||||
db.Insertable(new UnitJsonTest()
|
||||
{
|
||||
Name = "json1",
|
||||
Order = new Order { Id = 1, Name = "order1" }
|
||||
}).ExecuteCommand();
|
||||
|
||||
// Query all records from the table
|
||||
// 查询表中的所有记录
|
||||
var list = db.Queryable<UnitJsonTest>().ToList();
|
||||
|
||||
//Sqlfunc.JsonXXX
|
||||
var list2=db.Queryable<UnitJsonTest>()
|
||||
.Select(it => new
|
||||
{
|
||||
id=it.Id,
|
||||
jsonname=SqlFunc.JsonField(it.Order,"Name")
|
||||
})
|
||||
.ToList();
|
||||
|
||||
var list3=db.Queryable<UnitJsonTest>().Select(it => new
|
||||
{
|
||||
|
||||
Order1 = new UnitJsonTest()
|
||||
{
|
||||
Id=it.Id,
|
||||
Order = it.Order
|
||||
}
|
||||
}).ToList();
|
||||
|
||||
if (list3.First().Order1.Order == null|| list3.First().Order1.Order.Id==0)
|
||||
{
|
||||
throw new Exception("unit error");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a class with a JSON property.
|
||||
/// 表示一个包含 JSON 属性的类。
|
||||
/// </summary>
|
||||
[SugarTable("UnitJsonTest_a7")]
|
||||
public class UnitJsonTest
|
||||
{
|
||||
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
[SugarColumn(IsJson = true)]
|
||||
public Order Order { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents an order entity.
|
||||
/// 表示订单实体。
|
||||
/// </summary>
|
||||
public class Order
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
68
Src/Asp.NetCore2/DuckDBTest/a8_SelectReturnType.cs
Normal file
68
Src/Asp.NetCore2/DuckDBTest/a8_SelectReturnType.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using SqlSugar;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace OrmTest
|
||||
{
|
||||
internal class _a8_SelectReturnType
|
||||
{
|
||||
internal static void Init()
|
||||
{
|
||||
var db = DbHelper.GetNewDb();
|
||||
|
||||
//Create table
|
||||
//建表
|
||||
db.CodeFirst.InitTables<Student>();
|
||||
//init data
|
||||
db.Insertable(new Student() { CreateTime = DateTime.Now, Name = "aa" }).ExecuteCommand();
|
||||
|
||||
|
||||
// 返回匿名对象 (Return anonymous objects)
|
||||
var dynamicList = db.Queryable<Student>().Select<dynamic>().ToList();
|
||||
// SELECT * FROM Student_a8
|
||||
|
||||
// 手动:返回匿名集合,支持跨程序集 (Manually: Return an anonymous collection, supporting cross-assembly)
|
||||
List<dynamic> dynamicListCrossAssembly = db.Queryable<Student>().Select(it => (dynamic)new { id = it.Id }).ToList();
|
||||
// SELECT id AS id FROM Student_a8
|
||||
|
||||
// 手动:返回匿名集合,不能跨程序集 (Manually: Return an anonymous collection, within the same assembly)
|
||||
var dynamicListWithinAssembly = db.Queryable<Student>().Select(it => new { id = it.Id }).ToList();
|
||||
// SELECT id AS id FROM Student_a8
|
||||
|
||||
// 手动:返回类集合-手动 (Manually: Return a class collection manually)
|
||||
List<Student> classList = db.Queryable<Student>().Select(it => new Student { Id = it.Id }).ToList();
|
||||
// SELECT id AS Id FROM Student_a8
|
||||
|
||||
// 自动返回DTO集合: 请升级至 5.1.3.2 版本 (Automatically return DTO collections: Upgrade to version 5.1.3.2)
|
||||
var listDto = db.Queryable<Student>().Select<StudentDto>().ToList();
|
||||
|
||||
// 自动返回DTO: 请升级至 5.1.3.35 版本 (Automatically return DTO: Upgrade to version 5.1.3.35)
|
||||
var listDtoAutoMap = db.Queryable<Student>()
|
||||
.Select(it => new StudentDto
|
||||
{
|
||||
AppendColumn = 100 // 手动指定一列在自动映射 (Manually specify a column in automatic mapping)
|
||||
},
|
||||
true) // true 表示开启自动映射 (true indicates enabling automatic mapping)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
// 学生表的实体类 (Entity class for the Student table)
|
||||
[SugarTable("Student_a8")]
|
||||
public class Student
|
||||
{
|
||||
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public DateTime CreateTime { get; set; }
|
||||
}
|
||||
|
||||
// DTO 数据传输对象 (DTO - Data Transfer Object)
|
||||
public class StudentDto
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public DateTime CreateTime { get; set; }
|
||||
public int AppendColumn { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace SqlSugar.DuckDB
|
||||
{
|
||||
public class DuckDBCodeFirst : CodeFirstProvider
|
||||
{
|
||||
protected override void ExistLogicEnd(List<EntityColumnInfo> dbColumns)
|
||||
{
|
||||
foreach (EntityColumnInfo column in dbColumns)
|
||||
{
|
||||
if (column.DefaultValue != null)
|
||||
{
|
||||
this.Context.DbMaintenance.AddDefaultValue(column.DbTableName,column.DbColumnName,column.DefaultValue.ToSqlValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
public override void NoExistLogic(EntityInfo entityInfo)
|
||||
{
|
||||
var tableName = GetTableName(entityInfo);
|
||||
//Check.Exception(entityInfo.Columns.Where(it => it.IsPrimarykey).Count() > 1, "Use Code First ,The primary key must not exceed 1");
|
||||
List<DbColumnInfo> columns = new List<DbColumnInfo>();
|
||||
if (entityInfo.Columns.HasValue())
|
||||
{
|
||||
foreach (var item in entityInfo.Columns.Where(it=>it.IsIgnore==false))
|
||||
{
|
||||
DbColumnInfo dbColumnInfo = this.EntityColumnToDbColumn(entityInfo, tableName, item);
|
||||
columns.Add(dbColumnInfo);
|
||||
}
|
||||
if (entityInfo.IsCreateTableFiledSort)
|
||||
{
|
||||
columns = columns.OrderBy(c => c.CreateTableFieldSort).ToList();
|
||||
}
|
||||
}
|
||||
columns = columns.OrderBy(it => it.IsPrimarykey ? 0 : 1).ToList();
|
||||
this.Context.DbMaintenance.CreateTable(tableName, columns,true);
|
||||
}
|
||||
protected override DbColumnInfo EntityColumnToDbColumn(EntityInfo entityInfo, string tableName, EntityColumnInfo item)
|
||||
{
|
||||
var propertyType = UtilMethods.GetUnderType(item.PropertyInfo);
|
||||
var result = new DbColumnInfo()
|
||||
{
|
||||
TableId = entityInfo.Columns.IndexOf(item),
|
||||
DbColumnName = item.DbColumnName.HasValue() ? item.DbColumnName : item.PropertyName,
|
||||
IsPrimarykey = item.IsPrimarykey,
|
||||
IsIdentity = item.IsIdentity,
|
||||
TableName = tableName,
|
||||
IsNullable = item.IsNullable,
|
||||
DefaultValue = item.DefaultValue,
|
||||
ColumnDescription = item.ColumnDescription,
|
||||
Length = item.Length,
|
||||
CreateTableFieldSort = item.CreateTableFieldSort
|
||||
};
|
||||
if (propertyType == UtilConstants.DecType)
|
||||
{
|
||||
result.Scale = item.DecimalDigits;
|
||||
result.DecimalDigits = item.DecimalDigits;
|
||||
}
|
||||
GetDbType(item, propertyType, result);
|
||||
if (result.DataType.Equals("varchar", StringComparison.CurrentCultureIgnoreCase) && result.Length == 0)
|
||||
{
|
||||
result.Length = 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected override void ConvertColumns(List<DbColumnInfo> dbColumns)
|
||||
{
|
||||
foreach (var item in dbColumns)
|
||||
{
|
||||
if (item.DataType == "DateTime")
|
||||
{
|
||||
item.Length = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ChangeKey(EntityInfo entityInfo, string tableName, EntityColumnInfo item)
|
||||
{
|
||||
this.Context.DbMaintenance.UpdateColumn(tableName, EntityColumnToDbColumn(entityInfo, tableName, item));
|
||||
if (!item.IsPrimarykey)
|
||||
this.Context.DbMaintenance.DropConstraint(tableName,null);
|
||||
if (item.IsPrimarykey)
|
||||
this.Context.DbMaintenance.AddPrimaryKey(tableName, item.DbColumnName);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace SqlSugar.DuckDB
|
||||
{
|
||||
public class DuckDBDbBind : DbBindProvider
|
||||
{
|
||||
public override string GetDbTypeName(string csharpTypeName)
|
||||
{
|
||||
if (csharpTypeName == UtilConstants.ByteArrayType.Name)
|
||||
return "bytea";
|
||||
if (csharpTypeName.ToLower() == "int32")
|
||||
csharpTypeName = "int";
|
||||
if (csharpTypeName.ToLower() == "int16")
|
||||
csharpTypeName = "short";
|
||||
if (csharpTypeName.ToLower() == "int64")
|
||||
csharpTypeName = "long";
|
||||
if (csharpTypeName.ToLower().IsIn("boolean", "bool"))
|
||||
csharpTypeName = "bool";
|
||||
if (csharpTypeName == "DateTimeOffset")
|
||||
csharpTypeName = "DateTime";
|
||||
var mappings = this.MappingTypes.Where(it => it.Value.ToString().Equals(csharpTypeName, StringComparison.CurrentCultureIgnoreCase)).ToList();
|
||||
if (mappings != null && mappings.Count > 0)
|
||||
return mappings.First().Key;
|
||||
else
|
||||
return "varchar";
|
||||
}
|
||||
public override string GetPropertyTypeName(string dbTypeName)
|
||||
{
|
||||
dbTypeName = dbTypeName.ToLower();
|
||||
var propertyTypes = MappingTypes.Where(it => it.Value.ToString().ToLower() == dbTypeName || it.Key.ToLower() == dbTypeName);
|
||||
if (propertyTypes == null)
|
||||
{
|
||||
return "other";
|
||||
}
|
||||
else if (dbTypeName == "xml" || dbTypeName == "string"|| dbTypeName == "jsonb"|| dbTypeName == "json")
|
||||
{
|
||||
return "string";
|
||||
}else if (dbTypeName == "bpchar")//数据库char datatype 查询出来的时候是 bpchar
|
||||
{
|
||||
return "char";
|
||||
}
|
||||
if (dbTypeName == "byte[]")
|
||||
{
|
||||
return "byte[]";
|
||||
}
|
||||
else if (propertyTypes == null || propertyTypes.Count() == 0)
|
||||
{
|
||||
if (dbTypeName.StartsWith("_"))
|
||||
{
|
||||
var dbTypeName2 = dbTypeName.TrimStart('_');
|
||||
return MappingTypes.Where(it => it.Value.ToString().ToLower() == dbTypeName2 || it.Key.ToLower() == dbTypeName2).Select(it => it.Value + "[]").First();
|
||||
}
|
||||
Check.ThrowNotSupportedException(string.Format(" \"{0}\" Type NotSupported, DbBindProvider.GetPropertyTypeName error.", dbTypeName));
|
||||
return null;
|
||||
}
|
||||
else if (propertyTypes.First().Value == CSharpDataType.byteArray)
|
||||
{
|
||||
return "byte[]";
|
||||
}
|
||||
else
|
||||
{
|
||||
return propertyTypes.First().Value.ToString();
|
||||
}
|
||||
}
|
||||
public override List<KeyValuePair<string, CSharpDataType>> MappingTypes
|
||||
{
|
||||
get
|
||||
{
|
||||
var extService = this.Context.CurrentConnectionConfig.ConfigureExternalServices;
|
||||
if (extService != null && extService.AppendDataReaderTypeMappings.HasValue())
|
||||
{
|
||||
return extService.AppendDataReaderTypeMappings.Union(MappingTypesConst).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
return MappingTypesConst;
|
||||
}
|
||||
}
|
||||
}
|
||||
public static List<KeyValuePair<string, CSharpDataType>> MappingTypesConst = new List<KeyValuePair<string, CSharpDataType>>(){
|
||||
|
||||
new KeyValuePair<string, CSharpDataType>("int2",CSharpDataType.@short),
|
||||
new KeyValuePair<string, CSharpDataType>("int1",CSharpDataType.@byte),
|
||||
new KeyValuePair<string, CSharpDataType>("smallint",CSharpDataType.@short),
|
||||
new KeyValuePair<string, CSharpDataType>("int4",CSharpDataType.@int),
|
||||
new KeyValuePair<string, CSharpDataType>("serial",CSharpDataType.@int),
|
||||
new KeyValuePair<string, CSharpDataType>("integer",CSharpDataType.@int),
|
||||
new KeyValuePair<string, CSharpDataType>("int8",CSharpDataType.@long),
|
||||
new KeyValuePair<string, CSharpDataType>("bigint",CSharpDataType.@long),
|
||||
new KeyValuePair<string, CSharpDataType>("float4",CSharpDataType.@float),
|
||||
new KeyValuePair<string, CSharpDataType>("float4",CSharpDataType.Single),
|
||||
new KeyValuePair<string, CSharpDataType>("real",CSharpDataType.@float),
|
||||
new KeyValuePair<string, CSharpDataType>("float8",CSharpDataType.@double),
|
||||
new KeyValuePair<string, CSharpDataType>("double precision",CSharpDataType.@int),
|
||||
new KeyValuePair<string, CSharpDataType>("numeric",CSharpDataType.@decimal),
|
||||
new KeyValuePair<string, CSharpDataType>("decimal",CSharpDataType.@decimal),
|
||||
new KeyValuePair<string, CSharpDataType>("path",CSharpDataType.@decimal),
|
||||
new KeyValuePair<string, CSharpDataType>("point",CSharpDataType.@decimal),
|
||||
new KeyValuePair<string, CSharpDataType>("polygon",CSharpDataType.@decimal),
|
||||
|
||||
new KeyValuePair<string, CSharpDataType>("boolean",CSharpDataType.@bool),
|
||||
new KeyValuePair<string, CSharpDataType>("bool",CSharpDataType.@bool),
|
||||
new KeyValuePair<string, CSharpDataType>("box",CSharpDataType.@bool),
|
||||
new KeyValuePair<string, CSharpDataType>("bytea",CSharpDataType.byteArray),
|
||||
|
||||
new KeyValuePair<string, CSharpDataType>("varchar",CSharpDataType.@string),
|
||||
new KeyValuePair<string, CSharpDataType>("character varying",CSharpDataType.@string),
|
||||
new KeyValuePair<string, CSharpDataType>("geometry",CSharpDataType.@string),
|
||||
new KeyValuePair<string, CSharpDataType>("name",CSharpDataType.@string),
|
||||
new KeyValuePair<string, CSharpDataType>("text",CSharpDataType.@string),
|
||||
new KeyValuePair<string, CSharpDataType>("char",CSharpDataType.@string),
|
||||
new KeyValuePair<string, CSharpDataType>("character",CSharpDataType.@string),
|
||||
new KeyValuePair<string, CSharpDataType>("cidr",CSharpDataType.@string),
|
||||
new KeyValuePair<string, CSharpDataType>("circle",CSharpDataType.@string),
|
||||
new KeyValuePair<string, CSharpDataType>("tsquery",CSharpDataType.@string),
|
||||
new KeyValuePair<string, CSharpDataType>("tsvector",CSharpDataType.@string),
|
||||
new KeyValuePair<string, CSharpDataType>("txid_snapshot",CSharpDataType.@string),
|
||||
new KeyValuePair<string, CSharpDataType>("uuid",CSharpDataType.Guid),
|
||||
new KeyValuePair<string, CSharpDataType>("xml",CSharpDataType.@string),
|
||||
new KeyValuePair<string, CSharpDataType>("json",CSharpDataType.@string),
|
||||
|
||||
new KeyValuePair<string, CSharpDataType>("interval",CSharpDataType.@decimal),
|
||||
new KeyValuePair<string, CSharpDataType>("lseg",CSharpDataType.@decimal),
|
||||
new KeyValuePair<string, CSharpDataType>("macaddr",CSharpDataType.@decimal),
|
||||
new KeyValuePair<string, CSharpDataType>("money",CSharpDataType.@decimal),
|
||||
new KeyValuePair<string, CSharpDataType>("timestamp",CSharpDataType.DateTime),
|
||||
new KeyValuePair<string, CSharpDataType>("timestamp with time zone",CSharpDataType.DateTime),
|
||||
new KeyValuePair<string, CSharpDataType>("timestamptz",CSharpDataType.DateTime),
|
||||
new KeyValuePair<string, CSharpDataType>("timestamp without time zone",CSharpDataType.DateTime),
|
||||
new KeyValuePair<string, CSharpDataType>("date",CSharpDataType.DateTime),
|
||||
new KeyValuePair<string, CSharpDataType>("time",CSharpDataType.DateTime),
|
||||
new KeyValuePair<string, CSharpDataType>("time with time zone",CSharpDataType.DateTime),
|
||||
new KeyValuePair<string, CSharpDataType>("timetz",CSharpDataType.DateTime),
|
||||
new KeyValuePair<string, CSharpDataType>("time without time zone",CSharpDataType.DateTime),
|
||||
|
||||
new KeyValuePair<string, CSharpDataType>("bit",CSharpDataType.byteArray),
|
||||
new KeyValuePair<string, CSharpDataType>("bit varying",CSharpDataType.byteArray),
|
||||
new KeyValuePair<string, CSharpDataType>("varbit",CSharpDataType.@byte),
|
||||
new KeyValuePair<string, CSharpDataType>("time",CSharpDataType.TimeSpan),
|
||||
new KeyValuePair<string, CSharpDataType>("public.geometry",CSharpDataType.@object),
|
||||
new KeyValuePair<string, CSharpDataType>("public.geography",CSharpDataType.@object),
|
||||
new KeyValuePair<string, CSharpDataType>("inet",CSharpDataType.@object)
|
||||
};
|
||||
public override List<string> StringThrow
|
||||
{
|
||||
get
|
||||
{
|
||||
return new List<string>() { "int32", "datetime", "decimal", "double", "byte" };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace SqlSugar.DuckDB
|
||||
{
|
||||
public class DuckDBDbFirst : DbFirstProvider
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,516 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace SqlSugar.DuckDB
|
||||
{
|
||||
public class DuckDBDbMaintenance : DbMaintenanceProvider
|
||||
{
|
||||
#region DML
|
||||
protected override string GetDataBaseSql
|
||||
{
|
||||
get
|
||||
{
|
||||
return "SELECT datname FROM pg_database";
|
||||
}
|
||||
}
|
||||
protected override string GetColumnInfosByTableNameSql
|
||||
{
|
||||
get
|
||||
{
|
||||
string schema = GetSchema();
|
||||
string sql = @"select cast (pclass.oid as int4) as TableId,cast(ptables.tablename as varchar) as TableName,
|
||||
pcolumn.column_name as DbColumnName,pcolumn.udt_name as DataType,
|
||||
CASE WHEN pcolumn.numeric_scale >0 THEN pcolumn.numeric_precision ELSE pcolumn.character_maximum_length END as Length,
|
||||
pcolumn.column_default as DefaultValue,
|
||||
pcolumn.numeric_scale as DecimalDigits,
|
||||
pcolumn.numeric_scale as Scale,
|
||||
col_description(pclass.oid, pcolumn.ordinal_position) as ColumnDescription,
|
||||
case when pkey.colname = pcolumn.column_name
|
||||
then true else false end as IsPrimaryKey,
|
||||
case when pcolumn.column_default like 'nextval%'
|
||||
then true else false end as IsIdentity,
|
||||
case when pcolumn.is_nullable = 'YES'
|
||||
then true else false end as IsNullable
|
||||
from (select * from pg_tables where upper(tablename) = upper('{0}') and schemaname='" + schema + @"') ptables inner join pg_class pclass
|
||||
on ptables.tablename = pclass.relname inner join (SELECT *
|
||||
FROM information_schema.columns
|
||||
) pcolumn on pcolumn.table_name = ptables.tablename
|
||||
left join (
|
||||
select pg_class.relname,pg_attribute.attname as colname from
|
||||
pg_constraint inner join pg_class
|
||||
on pg_constraint.conrelid = pg_class.oid
|
||||
inner join pg_attribute on pg_attribute.attrelid = pg_class.oid
|
||||
and pg_attribute.attnum = pg_constraint.conkey[1]
|
||||
inner join pg_type on pg_type.oid = pg_attribute.atttypid
|
||||
where pg_constraint.contype='p'
|
||||
) pkey on pcolumn.table_name = pkey.relname
|
||||
order by table_catalog, table_schema, ordinal_position";
|
||||
return sql;
|
||||
}
|
||||
}
|
||||
|
||||
protected override string GetTableInfoListSql
|
||||
{
|
||||
get
|
||||
{
|
||||
var schema = GetSchema();
|
||||
return @"select cast(relname as varchar) as Name,
|
||||
cast(obj_description(c.oid,'pg_class') as varchar) as Description from pg_class c
|
||||
inner join
|
||||
pg_namespace n on n.oid = c.relnamespace and nspname='" + schema + @"'
|
||||
inner join
|
||||
pg_tables z on z.tablename=c.relname
|
||||
where relkind in('p', 'r') and relname not like 'hg_%' and relname not like 'sql_%' and schemaname='" + schema + "' order by relname";
|
||||
}
|
||||
}
|
||||
protected override string GetViewInfoListSql
|
||||
{
|
||||
get
|
||||
{
|
||||
return @"select cast(relname as varchar) as Name,cast(Description as varchar) from pg_description
|
||||
join pg_class on pg_description.objoid = pg_class.oid
|
||||
where objsubid = 0 and relname in (SELECT viewname from pg_views
|
||||
WHERE schemaname ='"+GetSchema()+"')";
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region DDL
|
||||
protected override string CreateDataBaseSql
|
||||
{
|
||||
get
|
||||
{
|
||||
return "CREATE DATABASE {0}";
|
||||
}
|
||||
}
|
||||
protected override string AddPrimaryKeySql
|
||||
{
|
||||
get
|
||||
{
|
||||
return "ALTER TABLE {0} ADD PRIMARY KEY({2}) /*{1}*/";
|
||||
}
|
||||
}
|
||||
protected override string AddColumnToTableSql
|
||||
{
|
||||
get
|
||||
{
|
||||
return "ALTER TABLE {0} ADD COLUMN {1} {2}{3} {4} {5} {6}";
|
||||
}
|
||||
}
|
||||
protected override string AlterColumnToTableSql
|
||||
{
|
||||
get
|
||||
{
|
||||
return "alter table {0} ALTER COLUMN {1} {2}{3} {4} {5} {6}";
|
||||
}
|
||||
}
|
||||
protected override string BackupDataBaseSql
|
||||
{
|
||||
get
|
||||
{
|
||||
return "mysqldump.exe {0} -uroot -p > {1} ";
|
||||
}
|
||||
}
|
||||
protected override string CreateTableSql
|
||||
{
|
||||
get
|
||||
{
|
||||
return "CREATE TABLE {0}(\r\n{1} $PrimaryKey)";
|
||||
}
|
||||
}
|
||||
protected override string CreateTableColumn
|
||||
{
|
||||
get
|
||||
{
|
||||
return "{0} {1}{2} {3} {4} {5}";
|
||||
}
|
||||
}
|
||||
protected override string TruncateTableSql
|
||||
{
|
||||
get
|
||||
{
|
||||
return "TRUNCATE TABLE {0}";
|
||||
}
|
||||
}
|
||||
protected override string BackupTableSql
|
||||
{
|
||||
get
|
||||
{
|
||||
return "create table {0} as (select * from {1} limit {2} offset 0)";
|
||||
}
|
||||
}
|
||||
protected override string DropTableSql
|
||||
{
|
||||
get
|
||||
{
|
||||
return "DROP TABLE {0}";
|
||||
}
|
||||
}
|
||||
protected override string DropColumnToTableSql
|
||||
{
|
||||
get
|
||||
{
|
||||
return "ALTER TABLE {0} DROP COLUMN {1}";
|
||||
}
|
||||
}
|
||||
protected override string DropConstraintSql
|
||||
{
|
||||
get
|
||||
{
|
||||
return "ALTER TABLE {0} DROP CONSTRAINT {1}";
|
||||
}
|
||||
}
|
||||
protected override string RenameColumnSql
|
||||
{
|
||||
get
|
||||
{
|
||||
return "ALTER TABLE {0} RENAME {1} TO {2}";
|
||||
}
|
||||
}
|
||||
protected override string AddColumnRemarkSql => "comment on column {1}.{0} is '{2}'";
|
||||
|
||||
protected override string DeleteColumnRemarkSql => "comment on column {1}.{0} is ''";
|
||||
|
||||
protected override string IsAnyColumnRemarkSql { get { throw new NotSupportedException(); } }
|
||||
|
||||
protected override string AddTableRemarkSql => "comment on table {0} is '{1}'";
|
||||
|
||||
protected override string DeleteTableRemarkSql => "comment on table {0} is ''";
|
||||
|
||||
protected override string IsAnyTableRemarkSql { get { throw new NotSupportedException(); } }
|
||||
|
||||
protected override string RenameTableSql => "alter table {0} to {1}";
|
||||
|
||||
protected override string CreateIndexSql
|
||||
{
|
||||
get
|
||||
{
|
||||
return "CREATE {3} INDEX Index_{0}_{2} ON {0} ({1})";
|
||||
}
|
||||
}
|
||||
protected override string AddDefaultValueSql
|
||||
{
|
||||
get
|
||||
{
|
||||
return "ALTER TABLE {0} ALTER COLUMN {1} SET DEFAULT {2}";
|
||||
}
|
||||
}
|
||||
protected override string IsAnyIndexSql
|
||||
{
|
||||
get
|
||||
{
|
||||
return " SELECT count(1) WHERE upper('{0}') IN ( SELECT upper(indexname) FROM pg_indexes )";
|
||||
}
|
||||
}
|
||||
protected override string IsAnyProcedureSql => throw new NotImplementedException();
|
||||
#endregion
|
||||
|
||||
#region Check
|
||||
protected override string CheckSystemTablePermissionsSql
|
||||
{
|
||||
get
|
||||
{
|
||||
return "select 1 from information_schema.columns limit 1 offset 0";
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Scattered
|
||||
protected override string CreateTableNull
|
||||
{
|
||||
get
|
||||
{
|
||||
return "DEFAULT NULL";
|
||||
}
|
||||
}
|
||||
protected override string CreateTableNotNull
|
||||
{
|
||||
get
|
||||
{
|
||||
return "NOT NULL";
|
||||
}
|
||||
}
|
||||
protected override string CreateTablePirmaryKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return "PRIMARY KEY";
|
||||
}
|
||||
}
|
||||
protected override string CreateTableIdentity
|
||||
{
|
||||
get
|
||||
{
|
||||
return "serial";
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
public override List<string> GetIndexList(string tableName)
|
||||
{
|
||||
var sql = $"SELECT indexname, indexdef FROM pg_indexes WHERE upper(tablename) = upper('{tableName}')";
|
||||
return this.Context.Ado.SqlQuery<string>(sql);
|
||||
}
|
||||
public override List<string> GetProcList(string dbName)
|
||||
{
|
||||
var sql = $"SELECT proname FROM pg_proc p JOIN pg_namespace n ON p.pronamespace = n.oid WHERE n.nspname = '{dbName}'";
|
||||
return this.Context.Ado.SqlQuery<string>(sql);
|
||||
}
|
||||
public override bool AddDefaultValue(string tableName, string columnName, string defaultValue)
|
||||
{
|
||||
return base.AddDefaultValue(this.SqlBuilder.GetTranslationTableName(tableName), this.SqlBuilder.GetTranslationTableName(columnName), defaultValue);
|
||||
}
|
||||
public override bool AddColumnRemark(string columnName, string tableName, string description)
|
||||
{
|
||||
tableName = this.SqlBuilder.GetTranslationTableName(tableName);
|
||||
string sql = string.Format(this.AddColumnRemarkSql, this.SqlBuilder.GetTranslationColumnName(columnName.ToLower(isAutoToLowerCodeFirst)), tableName, description);
|
||||
this.Context.Ado.ExecuteCommand(sql);
|
||||
return true;
|
||||
}
|
||||
public override bool AddTableRemark(string tableName, string description)
|
||||
{
|
||||
tableName = this.SqlBuilder.GetTranslationTableName(tableName);
|
||||
return base.AddTableRemark(tableName, description);
|
||||
}
|
||||
public override bool UpdateColumn(string tableName, DbColumnInfo columnInfo)
|
||||
{
|
||||
tableName = this.SqlBuilder.GetTranslationTableName(tableName);
|
||||
var columnName= this.SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName);
|
||||
string sql = GetUpdateColumnSql(tableName, columnInfo);
|
||||
this.Context.Ado.ExecuteCommand(sql);
|
||||
var isnull = columnInfo.IsNullable?" DROP NOT NULL ": " SET NOT NULL ";
|
||||
this.Context.Ado.ExecuteCommand(string.Format("alter table {0} alter {1} {2}",tableName,columnName, isnull));
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override string GetUpdateColumnSql(string tableName, DbColumnInfo columnInfo)
|
||||
{
|
||||
string columnName = this.SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName);
|
||||
tableName = this.SqlBuilder.GetTranslationTableName(tableName);
|
||||
string dataSize = GetSize(columnInfo);
|
||||
string dataType = columnInfo.DataType;
|
||||
if (!string.IsNullOrEmpty(dataType))
|
||||
{
|
||||
dataType = " type " + dataType;
|
||||
}
|
||||
string nullType = "";
|
||||
string primaryKey = null;
|
||||
string identity = null;
|
||||
string result = string.Format(this.AlterColumnToTableSql, tableName, columnName, dataType, dataSize, nullType, primaryKey, identity);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///by current connection string
|
||||
/// </summary>
|
||||
/// <param name="databaseDirectory"></param>
|
||||
/// <returns></returns>
|
||||
public override bool CreateDatabase(string databaseName, string databaseDirectory = null)
|
||||
{
|
||||
if (databaseDirectory != null)
|
||||
{
|
||||
if (!FileHelper.IsExistDirectory(databaseDirectory))
|
||||
{
|
||||
FileHelper.CreateDirectory(databaseDirectory);
|
||||
}
|
||||
}
|
||||
// var oldDatabaseName = this.Context.Ado.Connection.Database;
|
||||
//var connection = this.Context.CurrentConnectionConfig.ConnectionString;
|
||||
//connection = connection.Replace(oldDatabaseName, "");
|
||||
if (this.Context.Ado.IsValidConnection())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
var newDb = this.Context.CopyNew();
|
||||
newDb.Ado.Connection.ChangeDatabase("highgo");
|
||||
newDb.Open();
|
||||
if (!GetDataBaseList(newDb).Any(it => it.Equals(databaseName, StringComparison.CurrentCultureIgnoreCase)))
|
||||
{
|
||||
newDb.Ado.ExecuteCommand(string.Format(CreateDataBaseSql, this.SqlBuilder.SqlTranslationLeft+databaseName+this.SqlBuilder.SqlTranslationRight, databaseDirectory));
|
||||
}
|
||||
newDb.Close();
|
||||
return true;
|
||||
}
|
||||
public override bool AddRemark(EntityInfo entity)
|
||||
{
|
||||
var db = this.Context;
|
||||
var columns = entity.Columns.Where(it => it.IsIgnore == false).ToList();
|
||||
|
||||
foreach (var item in columns)
|
||||
{
|
||||
if (item.ColumnDescription != null)
|
||||
{
|
||||
db.DbMaintenance.AddColumnRemark(item.DbColumnName, item.DbTableName, item.ColumnDescription);
|
||||
|
||||
}
|
||||
}
|
||||
//table remak
|
||||
if (entity.TableDescription != null)
|
||||
{
|
||||
db.DbMaintenance.AddTableRemark(entity.DbTableName, entity.TableDescription);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public override bool CreateTable(string tableName, List<DbColumnInfo> columns, bool isCreatePrimaryKey = true)
|
||||
{
|
||||
if (columns.HasValue())
|
||||
{
|
||||
foreach (var item in columns)
|
||||
{
|
||||
if (item.DbColumnName.Equals("GUID", StringComparison.CurrentCultureIgnoreCase) && item.Length == 0)
|
||||
{
|
||||
item.Length = 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
string sql = GetCreateTableSql(tableName, columns);
|
||||
string primaryKeyInfo = null;
|
||||
if (columns.Any(it => it.IsPrimarykey) && isCreatePrimaryKey)
|
||||
{
|
||||
primaryKeyInfo = string.Format(", Primary key({0})", string.Join(",", columns.Where(it => it.IsPrimarykey).Select(it => this.SqlBuilder.GetTranslationColumnName(it.DbColumnName.ToLower(isAutoToLowerCodeFirst)))));
|
||||
|
||||
}
|
||||
sql = sql.Replace("$PrimaryKey", primaryKeyInfo);
|
||||
this.Context.Ado.ExecuteCommand(sql);
|
||||
return true;
|
||||
}
|
||||
protected override string GetCreateTableSql(string tableName, List<DbColumnInfo> columns)
|
||||
{
|
||||
List<string> columnArray = new List<string>();
|
||||
Check.Exception(columns.IsNullOrEmpty(), "No columns found ");
|
||||
foreach (var item in columns)
|
||||
{
|
||||
string columnName = item.DbColumnName;
|
||||
string dataType = item.DataType;
|
||||
if (dataType == "varchar" && item.Length == 0)
|
||||
{
|
||||
item.Length = 1;
|
||||
}
|
||||
//if (dataType == "uuid")
|
||||
//{
|
||||
// item.Length = 50;
|
||||
// dataType = "varchar";
|
||||
//}
|
||||
string dataSize = item.Length > 0 ? string.Format("({0})", item.Length) : null;
|
||||
if (item.DecimalDigits > 0&&item.Length>0 && dataType == "numeric")
|
||||
{
|
||||
dataSize = $"({item.Length},{item.DecimalDigits})";
|
||||
}
|
||||
string nullType = item.IsNullable ? this.CreateTableNull : CreateTableNotNull;
|
||||
string primaryKey = null;
|
||||
string addItem = string.Format(this.CreateTableColumn, this.SqlBuilder.GetTranslationColumnName(columnName.ToLower(isAutoToLowerCodeFirst)), dataType, dataSize, nullType, primaryKey, "");
|
||||
if (item.IsIdentity)
|
||||
{
|
||||
string length = dataType.Substring(dataType.Length - 1);
|
||||
string identityDataType = "serial" + length;
|
||||
addItem = addItem.Replace(dataType, identityDataType);
|
||||
}
|
||||
columnArray.Add(addItem);
|
||||
}
|
||||
string tableString = string.Format(this.CreateTableSql, this.SqlBuilder.GetTranslationTableName(tableName.ToLower(isAutoToLowerCodeFirst)), string.Join(",\r\n", columnArray));
|
||||
return tableString;
|
||||
}
|
||||
public override bool IsAnyConstraint(string constraintName)
|
||||
{
|
||||
throw new NotSupportedException("PgSql IsAnyConstraint NotSupportedException");
|
||||
}
|
||||
public override bool BackupDataBase(string databaseName, string fullFileName)
|
||||
{
|
||||
Check.ThrowNotSupportedException("PgSql BackupDataBase NotSupported");
|
||||
return false;
|
||||
}
|
||||
|
||||
public override List<DbColumnInfo> GetColumnInfosByTableName(string tableName, bool isCache = true)
|
||||
{
|
||||
var result= base.GetColumnInfosByTableName(tableName.TrimEnd('"').TrimStart('"').ToLower(), isCache);
|
||||
if (result == null || result.Count() == 0)
|
||||
{
|
||||
result = base.GetColumnInfosByTableName(tableName, isCache);
|
||||
}
|
||||
try
|
||||
{
|
||||
string sql = $@"select
|
||||
kcu.column_name as key_column
|
||||
from information_schema.table_constraints tco
|
||||
join information_schema.key_column_usage kcu
|
||||
on kcu.constraint_name = tco.constraint_name
|
||||
and kcu.constraint_schema = tco.constraint_schema
|
||||
and kcu.constraint_name = tco.constraint_name
|
||||
where tco.constraint_type = 'PRIMARY KEY'
|
||||
and kcu.table_schema='{GetSchema()}' and
|
||||
upper(kcu.table_name)=upper('{tableName.TrimEnd('"').TrimStart('"')}')";
|
||||
List<string> pkList = new List<string>();
|
||||
if (isCache)
|
||||
{
|
||||
pkList=GetListOrCache<string>("GetColumnInfosByTableName_N_Pk"+tableName, sql);
|
||||
}
|
||||
else
|
||||
{
|
||||
pkList = this.Context.Ado.SqlQuery<string>(sql);
|
||||
}
|
||||
if (pkList.Count >1)
|
||||
{
|
||||
foreach (var item in result)
|
||||
{
|
||||
if (pkList.Select(it=>it.ToUpper()).Contains(item.DbColumnName.ToUpper()))
|
||||
{
|
||||
item.IsPrimarykey = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Helper
|
||||
private bool isAutoToLowerCodeFirst
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.Context.CurrentConnectionConfig.MoreSettings == null) return true;
|
||||
else if (
|
||||
this.Context.CurrentConnectionConfig.MoreSettings.PgSqlIsAutoToLower == false &&
|
||||
this.Context.CurrentConnectionConfig.MoreSettings?.PgSqlIsAutoToLowerCodeFirst == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
private string GetSchema()
|
||||
{
|
||||
var schema = "public";
|
||||
if (System.Text.RegularExpressions.Regex.IsMatch(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), "searchpath="))
|
||||
{
|
||||
var regValue = System.Text.RegularExpressions.Regex.Match(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), @"searchpath\=(\w+)").Groups[1].Value;
|
||||
if (regValue.HasValue())
|
||||
{
|
||||
schema = regValue;
|
||||
}
|
||||
}
|
||||
else if (System.Text.RegularExpressions.Regex.IsMatch(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), "search path="))
|
||||
{
|
||||
var regValue = System.Text.RegularExpressions.Regex.Match(this.Context.CurrentConnectionConfig.ConnectionString.ToLower(), @"search path\=(\w+)").Groups[1].Value;
|
||||
if (regValue.HasValue())
|
||||
{
|
||||
schema = regValue;
|
||||
}
|
||||
}
|
||||
|
||||
return schema;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
167
Src/Asp.NetCore2/SqlSugar.DuckDBCore/DuckDB/DuckDBProvider.cs
Normal file
167
Src/Asp.NetCore2/SqlSugar.DuckDBCore/DuckDB/DuckDBProvider.cs
Normal file
@@ -0,0 +1,167 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using DuckDB;
|
||||
using DuckDB.NET.Data;
|
||||
using DuckDB.NET.Native;
|
||||
|
||||
namespace SqlSugar.DuckDB
|
||||
{
|
||||
public partial class DuckDBProvider : AdoProvider
|
||||
{
|
||||
public DuckDBProvider()
|
||||
{
|
||||
if (StaticConfig.AppContext_ConvertInfinityDateTime == false)
|
||||
{
|
||||
AppContext.SetSwitch("DuckDB.EnableLegacyTimestampBehavior", true);
|
||||
AppContext.SetSwitch("DuckDB.DisableDateTimeInfinityConversions", true);
|
||||
}
|
||||
|
||||
}
|
||||
public override IDbConnection Connection
|
||||
{
|
||||
get
|
||||
{
|
||||
if (base._DbConnection == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var DuckDBConnectionString = base.Context.CurrentConnectionConfig.ConnectionString;
|
||||
base._DbConnection = new DuckDBConnection(DuckDBConnectionString);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
|
||||
}
|
||||
}
|
||||
return base._DbConnection;
|
||||
}
|
||||
set
|
||||
{
|
||||
base._DbConnection = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override void BeginTran(string transactionName)
|
||||
{
|
||||
base.BeginTran();
|
||||
}
|
||||
/// <summary>
|
||||
/// Only SqlServer
|
||||
/// </summary>
|
||||
/// <param name="iso"></param>
|
||||
/// <param name="transactionName"></param>
|
||||
public override void BeginTran(IsolationLevel iso, string transactionName)
|
||||
{
|
||||
base.BeginTran(iso);
|
||||
}
|
||||
public override IDataAdapter GetAdapter()
|
||||
{
|
||||
return new DuckDBDataAdapter();
|
||||
}
|
||||
public override DbCommand GetCommand(string sql, SugarParameter[] parameters)
|
||||
{
|
||||
DuckDBCommand sqlCommand = new DuckDBCommand(sql, (DuckDBConnection)this.Connection);
|
||||
sqlCommand.CommandType = this.CommandType;
|
||||
sqlCommand.CommandTimeout = this.CommandTimeOut;
|
||||
if (this.Transaction != null)
|
||||
{
|
||||
sqlCommand.Transaction = (DuckDBTransaction)this.Transaction;
|
||||
}
|
||||
if (parameters.HasValue())
|
||||
{
|
||||
IDataParameter[] ipars = ToIDbDataParameter(parameters);
|
||||
sqlCommand.Parameters.AddRange((DuckDBParameter[])ipars);
|
||||
}
|
||||
CheckConnection();
|
||||
return sqlCommand;
|
||||
}
|
||||
public override void SetCommandToAdapter(IDataAdapter dataAdapter, DbCommand command)
|
||||
{
|
||||
((DuckDBDataAdapter)dataAdapter).SelectCommand = (DuckDBCommand)command;
|
||||
}
|
||||
/// <summary>
|
||||
/// if mysql return MySqlParameter[] pars
|
||||
/// if sqlerver return SqlParameter[] pars ...
|
||||
/// </summary>
|
||||
/// <param name="parameters"></param>
|
||||
/// <returns></returns>
|
||||
public override IDataParameter[] ToIDbDataParameter(params SugarParameter[] parameters)
|
||||
{
|
||||
if (parameters == null || parameters.Length == 0) return null;
|
||||
DuckDBParameter[] result = new DuckDBParameter[parameters.Length];
|
||||
int index = 0;
|
||||
var isVarchar = this.Context.IsVarchar();
|
||||
foreach (var parameter in parameters)
|
||||
{
|
||||
if (parameter.Value == null) parameter.Value = DBNull.Value;
|
||||
if (parameter.Value is System.Data.SqlTypes.SqlDateTime && parameter.DbType == System.Data.DbType.AnsiString)
|
||||
{
|
||||
parameter.DbType = System.Data.DbType.DateTime;
|
||||
parameter.Value = DBNull.Value;
|
||||
}
|
||||
UNumber(parameter);
|
||||
var sqlParameter = new DuckDBParameter();
|
||||
sqlParameter.ParameterName = parameter.ParameterName;
|
||||
sqlParameter.Size = parameter.Size;
|
||||
sqlParameter.Value = parameter.Value;
|
||||
sqlParameter.DbType = parameter.DbType;
|
||||
sqlParameter.Direction = parameter.Direction;
|
||||
//if (parameter.IsJson)
|
||||
//{
|
||||
// sqlParameter.DuckDBDbType = DuckDBType.Json;
|
||||
//}
|
||||
if (sqlParameter.Direction == 0)
|
||||
{
|
||||
sqlParameter.Direction = ParameterDirection.Input;
|
||||
}
|
||||
result[index] = sqlParameter;
|
||||
if (sqlParameter.Direction.IsIn(ParameterDirection.Output, ParameterDirection.InputOutput, ParameterDirection.ReturnValue))
|
||||
{
|
||||
if (this.OutputParameters == null) this.OutputParameters = new List<IDataParameter>();
|
||||
this.OutputParameters.RemoveAll(it => it.ParameterName == sqlParameter.ParameterName);
|
||||
this.OutputParameters.Add(sqlParameter);
|
||||
}
|
||||
if (isVarchar && sqlParameter.DbType == System.Data.DbType.String)
|
||||
{
|
||||
sqlParameter.DbType = System.Data.DbType.AnsiString;
|
||||
}
|
||||
else if (sqlParameter.Value is DateTime && sqlParameter.DbType == System.Data.DbType.AnsiString)
|
||||
{
|
||||
sqlParameter.DbType = System.Data.DbType.DateTime;
|
||||
}
|
||||
++index;
|
||||
//if (parameter.CustomDbType != null&& parameter.CustomDbType is DuckDBDbType)
|
||||
//{
|
||||
// sqlParameter.DbType = ((DuckDBType)parameter.CustomDbType);
|
||||
//}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void UNumber(SugarParameter parameter)
|
||||
{
|
||||
if (parameter.DbType == System.Data.DbType.UInt16)
|
||||
{
|
||||
parameter.DbType = System.Data.DbType.Int16;
|
||||
parameter.Value = Convert.ToInt16(parameter.Value);
|
||||
}
|
||||
else if (parameter.DbType == System.Data.DbType.UInt32)
|
||||
{
|
||||
parameter.DbType = System.Data.DbType.Int32;
|
||||
parameter.Value = Convert.ToInt32(parameter.Value);
|
||||
}
|
||||
else if (parameter.DbType == System.Data.DbType.UInt64)
|
||||
{
|
||||
parameter.DbType = System.Data.DbType.Int64;
|
||||
parameter.Value = Convert.ToInt64(parameter.Value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SqlSugar.DuckDB
|
||||
{
|
||||
public class DuckDBInsertable<T> : InsertableProvider<T> where T : class, new()
|
||||
{
|
||||
public override int ExecuteReturnIdentity()
|
||||
{
|
||||
InsertBuilder.IsReturnIdentity = true;
|
||||
PreToSql();
|
||||
string identityColumn = GetIdentityColumn();
|
||||
string sql = InsertBuilder.ToSqlString().Replace("$PrimaryKey", this.SqlBuilder.GetTranslationColumnName(identityColumn));
|
||||
RestoreMapping();
|
||||
var result = Ado.GetScalar(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()).ObjToInt();
|
||||
After(sql, result);
|
||||
return result;
|
||||
}
|
||||
public override async Task<int> ExecuteReturnIdentityAsync()
|
||||
{
|
||||
InsertBuilder.IsReturnIdentity = true;
|
||||
PreToSql();
|
||||
string identityColumn = GetIdentityColumn();
|
||||
string sql = InsertBuilder.ToSqlString().Replace("$PrimaryKey", this.SqlBuilder.GetTranslationColumnName(identityColumn));
|
||||
RestoreMapping();
|
||||
var obj = await Ado.GetScalarAsync(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray());
|
||||
var result = obj.ObjToInt();
|
||||
After(sql, result);
|
||||
return result;
|
||||
}
|
||||
public override KeyValuePair<string, List<SugarParameter>> ToSql()
|
||||
{
|
||||
var result= base.ToSql();
|
||||
var primaryKey = GetPrimaryKeys().FirstOrDefault();
|
||||
if (primaryKey != null)
|
||||
{
|
||||
primaryKey = this.SqlBuilder.GetTranslationColumnName(primaryKey);
|
||||
}
|
||||
return new KeyValuePair<string, List<SugarParameter>>(result.Key.Replace("$PrimaryKey", primaryKey), result.Value);
|
||||
}
|
||||
|
||||
public override long ExecuteReturnBigIdentity()
|
||||
{
|
||||
InsertBuilder.IsReturnIdentity = true;
|
||||
PreToSql();
|
||||
string sql = InsertBuilder.ToSqlString().Replace("$PrimaryKey", this.SqlBuilder.GetTranslationColumnName(GetIdentityKeys().FirstOrDefault()));
|
||||
RestoreMapping();
|
||||
var result = Convert.ToInt64(Ado.GetScalar(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()) ?? "0");
|
||||
After(sql, result);
|
||||
return result;
|
||||
}
|
||||
public override async Task<long> ExecuteReturnBigIdentityAsync()
|
||||
{
|
||||
InsertBuilder.IsReturnIdentity = true;
|
||||
PreToSql();
|
||||
string sql = InsertBuilder.ToSqlString().Replace("$PrimaryKey", this.SqlBuilder.GetTranslationColumnName(GetIdentityKeys().FirstOrDefault()));
|
||||
RestoreMapping();
|
||||
var result = Convert.ToInt64(await Ado.GetScalarAsync(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray()) ?? "0");
|
||||
After(sql, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public override bool ExecuteCommandIdentityIntoEntity()
|
||||
{
|
||||
var result = InsertObjs.First();
|
||||
var identityKeys = GetIdentityKeys();
|
||||
if (identityKeys.Count == 0) { return this.ExecuteCommand() > 0; }
|
||||
var idValue = ExecuteReturnBigIdentity();
|
||||
Check.Exception(identityKeys.Count > 1, "ExecuteCommandIdentityIntoEntity does not support multiple identity keys");
|
||||
var identityKey = identityKeys.First();
|
||||
object setValue = 0;
|
||||
if (idValue > int.MaxValue)
|
||||
setValue = idValue;
|
||||
else
|
||||
setValue = Convert.ToInt32(idValue);
|
||||
var propertyName = this.Context.EntityMaintenance.GetPropertyName<T>(identityKey);
|
||||
typeof(T).GetProperties().First(t => t.Name.ToUpper() == propertyName.ToUpper()).SetValue(result, setValue, null);
|
||||
return idValue > 0;
|
||||
}
|
||||
|
||||
private string GetIdentityColumn()
|
||||
{
|
||||
var identityColumn = GetIdentityKeys().FirstOrDefault();
|
||||
if (identityColumn == null)
|
||||
{
|
||||
var columns = this.Context.DbMaintenance.GetColumnInfosByTableName(InsertBuilder.GetTableNameString);
|
||||
identityColumn = columns.First(it => it.IsIdentity || it.IsPrimarykey).DbColumnName;
|
||||
}
|
||||
return identityColumn;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SqlSugar.DuckDB
|
||||
{
|
||||
public class DuckDBQueryable<T> : QueryableProvider<T>
|
||||
{
|
||||
public override ISugarQueryable<T> With(string withString)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
public override ISugarQueryable<T> PartitionBy(string groupFileds)
|
||||
{
|
||||
this.GroupBy(groupFileds);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
public class DuckDBQueryable<T, T2> : QueryableProvider<T, T2>
|
||||
{
|
||||
public new ISugarQueryable<T, T2> With(string withString)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
}
|
||||
public class DuckDBQueryable<T, T2, T3> : QueryableProvider<T, T2, T3>
|
||||
{
|
||||
|
||||
}
|
||||
public class DuckDBQueryable<T, T2, T3, T4> : QueryableProvider<T, T2, T3, T4>
|
||||
{
|
||||
|
||||
}
|
||||
public class DuckDBQueryable<T, T2, T3, T4, T5> : QueryableProvider<T, T2, T3, T4, T5>
|
||||
{
|
||||
|
||||
}
|
||||
public class DuckDBQueryable<T, T2, T3, T4, T5, T6> : QueryableProvider<T, T2, T3, T4, T5, T6>
|
||||
{
|
||||
|
||||
}
|
||||
public class DuckDBQueryable<T, T2, T3, T4, T5, T6, T7> : QueryableProvider<T, T2, T3, T4, T5, T6, T7>
|
||||
{
|
||||
|
||||
}
|
||||
public class DuckDBQueryable<T, T2, T3, T4, T5, T6, T7, T8> : QueryableProvider<T, T2, T3, T4, T5, T6, T7, T8>
|
||||
{
|
||||
|
||||
}
|
||||
public class DuckDBQueryable<T, T2, T3, T4, T5, T6, T7, T8, T9> : QueryableProvider<T, T2, T3, T4, T5, T6, T7, T8, T9>
|
||||
{
|
||||
|
||||
}
|
||||
public class DuckDBQueryable<T, T2, T3, T4, T5, T6, T7, T8, T9, T10> : QueryableProvider<T, T2, T3, T4, T5, T6, T7, T8, T9, T10>
|
||||
{
|
||||
|
||||
}
|
||||
public class DuckDBQueryable<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> : QueryableProvider<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>
|
||||
{
|
||||
|
||||
}
|
||||
public class DuckDBQueryable<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> : QueryableProvider<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace SqlSugar.DuckDB
|
||||
{
|
||||
public class DuckDBBuilder : SqlBuilderProvider
|
||||
{
|
||||
public override string SqlTranslationLeft
|
||||
{
|
||||
get
|
||||
{
|
||||
return "\"";
|
||||
}
|
||||
}
|
||||
public override string SqlTranslationRight
|
||||
{
|
||||
get
|
||||
{
|
||||
return "\"";
|
||||
}
|
||||
}
|
||||
public override string SqlDateNow
|
||||
{
|
||||
get
|
||||
{
|
||||
return "current_date";
|
||||
}
|
||||
}
|
||||
public override string FullSqlDateNow
|
||||
{
|
||||
get
|
||||
{
|
||||
return "select current_date";
|
||||
}
|
||||
}
|
||||
|
||||
public bool isAutoToLower
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.Context.CurrentConnectionConfig.MoreSettings == null) return true;
|
||||
return this.Context.CurrentConnectionConfig.MoreSettings.PgSqlIsAutoToLower;
|
||||
}
|
||||
}
|
||||
public override string GetTranslationColumnName(string propertyName)
|
||||
{
|
||||
if (propertyName.Contains(".")&& !propertyName.Contains(SqlTranslationLeft))
|
||||
{
|
||||
return string.Join(".", propertyName.Split('.').Select(it => $"{SqlTranslationLeft}{it.ToLower(isAutoToLower)}{SqlTranslationRight}"));
|
||||
}
|
||||
|
||||
if (propertyName.Contains(SqlTranslationLeft)) return propertyName;
|
||||
else
|
||||
return SqlTranslationLeft + propertyName.ToLower(isAutoToLower) + SqlTranslationRight;
|
||||
}
|
||||
|
||||
//public override string GetNoTranslationColumnName(string name)
|
||||
//{
|
||||
// return name.TrimEnd(Convert.ToChar(SqlTranslationRight)).TrimStart(Convert.ToChar(SqlTranslationLeft)).ToLower();
|
||||
//}
|
||||
public override string GetTranslationColumnName(string entityName, string propertyName)
|
||||
{
|
||||
Check.ArgumentNullException(entityName, string.Format(ErrorMessage.ObjNotExist, "Table Name"));
|
||||
Check.ArgumentNullException(propertyName, string.Format(ErrorMessage.ObjNotExist, "Column Name"));
|
||||
var context = this.Context;
|
||||
var mappingInfo = context
|
||||
.MappingColumns
|
||||
.FirstOrDefault(it =>
|
||||
it.EntityName.Equals(entityName, StringComparison.CurrentCultureIgnoreCase) &&
|
||||
it.PropertyName.Equals(propertyName, StringComparison.CurrentCultureIgnoreCase));
|
||||
return (mappingInfo == null ? SqlTranslationLeft + propertyName.ToLower(isAutoToLower) + SqlTranslationRight : SqlTranslationLeft + mappingInfo.DbColumnName.ToLower(isAutoToLower) + SqlTranslationRight);
|
||||
}
|
||||
|
||||
public override string GetTranslationTableName(string name)
|
||||
{
|
||||
Check.ArgumentNullException(name, string.Format(ErrorMessage.ObjNotExist, "Table Name"));
|
||||
var context = this.Context;
|
||||
|
||||
var mappingInfo = context
|
||||
.MappingTables
|
||||
.FirstOrDefault(it => it.EntityName.Equals(name, StringComparison.CurrentCultureIgnoreCase));
|
||||
if (mappingInfo == null && name.Contains(".") && name.Contains("\""))
|
||||
{
|
||||
return name;
|
||||
}
|
||||
name = (mappingInfo == null ? name : mappingInfo.DbTableName);
|
||||
if (name.Contains(".")&& !name.Contains("(")&&!name.Contains("\".\""))
|
||||
{
|
||||
return string.Join(".", name.ToLower(isAutoToLower).Split('.').Select(it => SqlTranslationLeft + it + SqlTranslationRight));
|
||||
}
|
||||
else if (name.Contains("("))
|
||||
{
|
||||
return name;
|
||||
}
|
||||
else if (name.Contains(SqlTranslationLeft) && name.Contains(SqlTranslationRight))
|
||||
{
|
||||
return name;
|
||||
}
|
||||
else
|
||||
{
|
||||
return SqlTranslationLeft + name.ToLower(isAutoToLower).TrimEnd('"').TrimStart('"') + SqlTranslationRight;
|
||||
}
|
||||
}
|
||||
public override string GetUnionFomatSql(string sql)
|
||||
{
|
||||
return " ( " + sql + " ) ";
|
||||
}
|
||||
|
||||
public override Type GetNullType(string tableName, string columnName)
|
||||
{
|
||||
if (tableName != null)
|
||||
tableName = tableName.Trim();
|
||||
var columnInfo=this.Context.DbMaintenance.GetColumnInfosByTableName(tableName).FirstOrDefault(z => z.DbColumnName?.ToLower()==columnName?.ToLower());
|
||||
if (columnInfo != null)
|
||||
{
|
||||
var cTypeName=this.Context.Ado.DbBind.GetCsharpTypeNameByDbTypeName(columnInfo.DataType);
|
||||
var value=SqlSugar.UtilMethods.GetTypeByTypeName(cTypeName);
|
||||
if (value != null)
|
||||
{
|
||||
var key = "GetNullType_" + tableName + columnName;
|
||||
return new ReflectionInoCacheService().GetOrCreate(key, () => value);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace SqlSugar.DuckDB
|
||||
{
|
||||
public class DuckDBDeleteBuilder : DeleteBuilder
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,488 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
namespace SqlSugar.DuckDB
|
||||
{
|
||||
public class DuckDBExpressionContext : ExpressionContext, ILambdaExpressions
|
||||
{
|
||||
public SqlSugarProvider Context { get; set; }
|
||||
public DuckDBExpressionContext()
|
||||
{
|
||||
base.DbMehtods = new DuckDBMethod();
|
||||
}
|
||||
public override string SqlTranslationLeft
|
||||
{
|
||||
get
|
||||
{
|
||||
return "\"";
|
||||
}
|
||||
}
|
||||
public override string SqlTranslationRight
|
||||
{
|
||||
get
|
||||
{
|
||||
return "\"";
|
||||
}
|
||||
}
|
||||
public override string GetTranslationText(string name)
|
||||
{
|
||||
return SqlTranslationLeft + name.ToLower(isAutoToLower) + SqlTranslationRight;
|
||||
}
|
||||
public bool isAutoToLower
|
||||
{
|
||||
get
|
||||
{
|
||||
return base.PgSqlIsAutoToLower;
|
||||
}
|
||||
}
|
||||
public override string GetTranslationTableName(string entityName, bool isMapping = true)
|
||||
{
|
||||
Check.ArgumentNullException(entityName, string.Format(ErrorMessage.ObjNotExist, "Table Name"));
|
||||
if (IsTranslationText(entityName)) return entityName;
|
||||
isMapping = isMapping && this.MappingTables.HasValue();
|
||||
var isComplex = entityName.Contains(UtilConstants.Dot);
|
||||
if (isMapping && isComplex)
|
||||
{
|
||||
var columnInfo = entityName.Split(UtilConstants.DotChar);
|
||||
var mappingInfo = this.MappingTables.FirstOrDefault(it => it.EntityName.Equals(columnInfo.Last(), StringComparison.CurrentCultureIgnoreCase));
|
||||
if (mappingInfo != null)
|
||||
{
|
||||
columnInfo[columnInfo.Length - 1] = mappingInfo.EntityName;
|
||||
}
|
||||
return string.Join(UtilConstants.Dot, columnInfo.Select(it => GetTranslationText(it)));
|
||||
}
|
||||
else if (isMapping)
|
||||
{
|
||||
var mappingInfo = this.MappingTables.FirstOrDefault(it => it.EntityName.Equals(entityName, StringComparison.CurrentCultureIgnoreCase));
|
||||
|
||||
var tableName = mappingInfo?.DbTableName+"";
|
||||
if (tableName.Contains("."))
|
||||
{
|
||||
tableName = string.Join(UtilConstants.Dot, tableName.Split(UtilConstants.DotChar).Select(it => GetTranslationText(it)));
|
||||
return tableName;
|
||||
}
|
||||
|
||||
return SqlTranslationLeft + (mappingInfo == null ? entityName : mappingInfo.DbTableName).ToLower(isAutoToLower) + SqlTranslationRight;
|
||||
}
|
||||
else if (isComplex)
|
||||
{
|
||||
return string.Join(UtilConstants.Dot, entityName.Split(UtilConstants.DotChar).Select(it => GetTranslationText(it)));
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetTranslationText(entityName);
|
||||
}
|
||||
}
|
||||
public override string GetTranslationColumnName(string columnName)
|
||||
{
|
||||
Check.ArgumentNullException(columnName, string.Format(ErrorMessage.ObjNotExist, "Column Name"));
|
||||
if (columnName.Substring(0, 1) == this.SqlParameterKeyWord)
|
||||
{
|
||||
return columnName;
|
||||
}
|
||||
if (IsTranslationText(columnName)) return columnName;
|
||||
if (columnName.Contains(UtilConstants.Dot))
|
||||
{
|
||||
return string.Join(UtilConstants.Dot, columnName.Split(UtilConstants.DotChar).Select(it => GetTranslationText(it)));
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetTranslationText(columnName);
|
||||
}
|
||||
}
|
||||
public override string GetDbColumnName(string entityName, string propertyName)
|
||||
{
|
||||
if (this.MappingColumns.HasValue())
|
||||
{
|
||||
var mappingInfo = this.MappingColumns.SingleOrDefault(it => it.EntityName == entityName && it.PropertyName == propertyName);
|
||||
return (mappingInfo == null ? propertyName : mappingInfo.DbColumnName).ToLower(isAutoToLower);
|
||||
}
|
||||
else
|
||||
{
|
||||
return propertyName.ToLower(isAutoToLower);
|
||||
}
|
||||
}
|
||||
|
||||
public string GetValue(object entityValue)
|
||||
{
|
||||
if (entityValue == null)
|
||||
return null;
|
||||
var type = UtilMethods.GetUnderType(entityValue.GetType());
|
||||
if (UtilConstants.NumericalTypes.Contains(type))
|
||||
{
|
||||
return entityValue.ToString();
|
||||
}
|
||||
else if (type == UtilConstants.DateType)
|
||||
{
|
||||
return this.DbMehtods.ToDate(new MethodCallExpressionModel()
|
||||
{
|
||||
Args = new System.Collections.Generic.List<MethodCallExpressionArgs>() {
|
||||
new MethodCallExpressionArgs(){ MemberName=$"'{entityValue}'" }
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.DbMehtods.ToString(new MethodCallExpressionModel()
|
||||
{
|
||||
Args = new System.Collections.Generic.List<MethodCallExpressionArgs>() {
|
||||
new MethodCallExpressionArgs(){ MemberName=$"'{entityValue}'" }
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
public class DuckDBMethod : DefaultDbMethod, IDbMethods
|
||||
{
|
||||
|
||||
public override string GetDateString(string dateValue, string formatString)
|
||||
{
|
||||
if (!(formatString?.Contains("24") == true))
|
||||
{
|
||||
formatString = formatString.Replace("HH", "hh24");
|
||||
if (!(formatString?.Contains("24") == true))
|
||||
{
|
||||
formatString = formatString.Replace("hh", "hh24");
|
||||
}
|
||||
}
|
||||
formatString = formatString.Replace("mm", "mi");
|
||||
return $"to_char({dateValue},'{formatString}') ";
|
||||
}
|
||||
public override string CharIndex(MethodCallExpressionModel model)
|
||||
{
|
||||
return string.Format(" (strpos ({1},{0})-1)", model.Args[0].MemberName, model.Args[1].MemberName);
|
||||
}
|
||||
public override string TrueValue()
|
||||
{
|
||||
return "true";
|
||||
}
|
||||
public override string FalseValue()
|
||||
{
|
||||
return "false";
|
||||
}
|
||||
public override string DateDiff(MethodCallExpressionModel model)
|
||||
{
|
||||
var parameter = (DateType)(Enum.Parse(typeof(DateType), model.Args[0].MemberValue.ObjToString()));
|
||||
var begin = model.Args[1].MemberName;
|
||||
var end = model.Args[2].MemberName;
|
||||
switch (parameter)
|
||||
{
|
||||
case DateType.Year:
|
||||
return $" ( DATE_PART('Year', {end} ) - DATE_PART('Year', {begin}) )";
|
||||
case DateType.Month:
|
||||
return $" ( ( DATE_PART('Year', {end} ) - DATE_PART('Year', {begin}) ) * 12 + (DATE_PART('month', {end}) - DATE_PART('month', {begin})) )";
|
||||
case DateType.Day:
|
||||
return $" ( DATE_PART('day', {end} - {begin}) )";
|
||||
case DateType.Hour:
|
||||
return $" ( ( DATE_PART('day', {end} - {begin}) ) * 24 + DATE_PART('hour', {end} - {begin} ) )";
|
||||
case DateType.Minute:
|
||||
return $" ( ( ( DATE_PART('day', {end} - {begin}) ) * 24 + DATE_PART('hour', {end} - {begin} ) ) * 60 + DATE_PART('minute', {end} - {begin} ) )";
|
||||
case DateType.Second:
|
||||
return $" ( ( ( DATE_PART('day', {end} - {begin}) ) * 24 + DATE_PART('hour', {end} - {begin} ) ) * 60 + DATE_PART('minute', {end} - {begin} ) ) * 60 + DATE_PART('second', {end} - {begin} )";
|
||||
case DateType.Millisecond:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
throw new Exception(parameter + " datediff no support");
|
||||
}
|
||||
public override string IIF(MethodCallExpressionModel model)
|
||||
{
|
||||
var parameter = model.Args[0];
|
||||
var parameter2 = model.Args[1];
|
||||
var parameter3 = model.Args[2];
|
||||
if (parameter.Type == UtilConstants.BoolType)
|
||||
{
|
||||
parameter.MemberName = parameter.MemberName.ToString().Replace("=1", "=true");
|
||||
parameter2.MemberName = false;
|
||||
parameter3.MemberName = true;
|
||||
}
|
||||
return string.Format("( CASE WHEN {0} THEN {1} ELSE {2} END )", parameter.MemberName, parameter2.MemberName, parameter3.MemberName);
|
||||
}
|
||||
public override string DateValue(MethodCallExpressionModel model)
|
||||
{
|
||||
var parameter = model.Args[0];
|
||||
var parameter2 = model.Args[1];
|
||||
var format = "dd";
|
||||
if (parameter2.MemberValue.ObjToString() == DateType.Year.ToString())
|
||||
{
|
||||
format = "yyyy";
|
||||
}
|
||||
if (parameter2.MemberValue.ObjToString() == DateType.Month.ToString())
|
||||
{
|
||||
format = "MM";
|
||||
}
|
||||
if (parameter2.MemberValue.ObjToString() == DateType.Day.ToString())
|
||||
{
|
||||
format = "dd";
|
||||
}
|
||||
if (parameter2.MemberValue.ObjToString() == DateType.Hour.ToString())
|
||||
{
|
||||
format = "hh";
|
||||
}
|
||||
if (parameter2.MemberValue.ObjToString() == DateType.Minute.ToString())
|
||||
{
|
||||
format = "mi";
|
||||
}
|
||||
if (parameter2.MemberValue.ObjToString() == DateType.Second.ToString())
|
||||
{
|
||||
format = "ss";
|
||||
}
|
||||
if (parameter2.MemberValue.ObjToString() == DateType.Millisecond.ToString())
|
||||
{
|
||||
format = "ms";
|
||||
}
|
||||
if (parameter2.MemberValue.ObjToString() == DateType.Weekday.ToString())
|
||||
{
|
||||
return $" extract(DOW FROM cast({parameter.MemberName} as TIMESTAMP)) ";
|
||||
}
|
||||
|
||||
return string.Format(" cast( to_char({1},'{0}')as integer ) ", format, parameter.MemberName);
|
||||
}
|
||||
|
||||
public override string Contains(MethodCallExpressionModel model)
|
||||
{
|
||||
var parameter = model.Args[0];
|
||||
var parameter2 = model.Args[1];
|
||||
return string.Format(" ({0} like concat('%',{1},'%')) ", parameter.MemberName, parameter2.MemberName );
|
||||
}
|
||||
|
||||
public override string StartsWith(MethodCallExpressionModel model)
|
||||
{
|
||||
var parameter = model.Args[0];
|
||||
var parameter2 = model.Args[1];
|
||||
return string.Format(" ({0} like concat({1},'%')) ", parameter.MemberName, parameter2.MemberName);
|
||||
}
|
||||
|
||||
public override string EndsWith(MethodCallExpressionModel model)
|
||||
{
|
||||
var parameter = model.Args[0];
|
||||
var parameter2 = model.Args[1];
|
||||
return string.Format(" ({0} like concat('%',{1}))", parameter.MemberName,parameter2.MemberName);
|
||||
}
|
||||
|
||||
public override string DateIsSameDay(MethodCallExpressionModel model)
|
||||
{
|
||||
var parameter = model.Args[0];
|
||||
var parameter2 = model.Args[1];
|
||||
return string.Format(" ( to_char({0},'yyyy-MM-dd')=to_char({1},'yyyy-MM-dd') ) ", parameter.MemberName, parameter2.MemberName); ;
|
||||
}
|
||||
|
||||
public override string HasValue(MethodCallExpressionModel model)
|
||||
{
|
||||
var parameter = model.Args[0];
|
||||
return string.Format("( {0} IS NOT NULL )", parameter.MemberName);
|
||||
}
|
||||
|
||||
public override string DateIsSameByType(MethodCallExpressionModel model)
|
||||
{
|
||||
var parameter = model.Args[0];
|
||||
var parameter2 = model.Args[1];
|
||||
var parameter3 = model.Args[2];
|
||||
DateType dateType =(DateType)parameter3.MemberValue;
|
||||
var format = "yyyy-MM-dd";
|
||||
if (dateType == DateType.Quarter)
|
||||
{
|
||||
return string.Format(" (date_trunc('quarter',{0})=date_trunc('quarter',{1}) ) ", parameter.MemberName, parameter2.MemberName,format);
|
||||
}
|
||||
switch (dateType)
|
||||
{
|
||||
case DateType.Year:
|
||||
format = "yyyy";
|
||||
break;
|
||||
case DateType.Month:
|
||||
format = "yyyy-MM";
|
||||
break;
|
||||
case DateType.Day:
|
||||
break;
|
||||
case DateType.Hour:
|
||||
format = "yyyy-MM-dd HH";
|
||||
break;
|
||||
case DateType.Second:
|
||||
format = "yyyy-MM-dd HH:mm:ss";
|
||||
break;
|
||||
case DateType.Minute:
|
||||
format = "yyyy-MM-dd HH:mm";
|
||||
break;
|
||||
case DateType.Millisecond:
|
||||
format = "yyyy-MM-dd HH:mm.ms";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return string.Format(" ( to_char({0},'{2}')=to_char({1},'{2}') ) ", parameter.MemberName, parameter2.MemberName, format);
|
||||
}
|
||||
|
||||
public override string ToDate(MethodCallExpressionModel model)
|
||||
{
|
||||
var parameter = model.Args[0];
|
||||
return string.Format(" CAST({0} AS timestamp)", parameter.MemberName);
|
||||
}
|
||||
public override string DateAddByType(MethodCallExpressionModel model)
|
||||
{
|
||||
var parameter = model.Args[0];
|
||||
var parameter2 = model.Args[1];
|
||||
var parameter3 = model.Args[2];
|
||||
return string.Format(" ({1} + ({2}||'{0}')::INTERVAL) ", parameter3.MemberValue, parameter.MemberName, parameter2.MemberName);
|
||||
}
|
||||
|
||||
public override string DateAddDay(MethodCallExpressionModel model)
|
||||
{
|
||||
var parameter = model.Args[0];
|
||||
var parameter2 = model.Args[1];
|
||||
return string.Format(" ({0} + ({1}||'day')::INTERVAL) ", parameter.MemberName, parameter2.MemberName);
|
||||
}
|
||||
|
||||
public override string ToInt32(MethodCallExpressionModel model)
|
||||
{
|
||||
var parameter = model.Args[0];
|
||||
return string.Format(" CAST({0} AS INT4)", parameter.MemberName);
|
||||
}
|
||||
|
||||
public override string ToInt64(MethodCallExpressionModel model)
|
||||
{
|
||||
var parameter = model.Args[0];
|
||||
return string.Format(" CAST({0} AS INT8)", parameter.MemberName);
|
||||
}
|
||||
|
||||
public override string ToString(MethodCallExpressionModel model)
|
||||
{
|
||||
var parameter = model.Args[0];
|
||||
return string.Format(" CAST({0} AS VARCHAR)", parameter.MemberName);
|
||||
}
|
||||
|
||||
public override string ToGuid(MethodCallExpressionModel model)
|
||||
{
|
||||
var parameter = model.Args[0];
|
||||
return string.Format(" CAST({0} AS UUID)", parameter.MemberName);
|
||||
}
|
||||
|
||||
public override string ToDouble(MethodCallExpressionModel model)
|
||||
{
|
||||
var parameter = model.Args[0];
|
||||
return string.Format(" CAST({0} AS DECIMAL(18,4))", parameter.MemberName);
|
||||
}
|
||||
|
||||
public override string ToBool(MethodCallExpressionModel model)
|
||||
{
|
||||
var parameter = model.Args[0];
|
||||
return string.Format(" CAST({0} AS boolean)", parameter.MemberName);
|
||||
}
|
||||
|
||||
public override string ToDecimal(MethodCallExpressionModel model)
|
||||
{
|
||||
var parameter = model.Args[0];
|
||||
return string.Format(" CAST({0} AS DECIMAL(18,4))", parameter.MemberName);
|
||||
}
|
||||
|
||||
public override string Length(MethodCallExpressionModel model)
|
||||
{
|
||||
var parameter = model.Args[0];
|
||||
return string.Format(" LENGTH({0})", parameter.MemberName);
|
||||
}
|
||||
public override string MergeString(params string[] strings)
|
||||
{
|
||||
return " concat("+string.Join(",", strings).Replace("+", "") + ") ";
|
||||
}
|
||||
public override string IsNull(MethodCallExpressionModel model)
|
||||
{
|
||||
var parameter = model.Args[0];
|
||||
var parameter1 = model.Args[1];
|
||||
return string.Format("(CASE WHEN {0} IS NULL THEN {1} ELSE {0} END)", parameter.MemberName, parameter1.MemberName);
|
||||
}
|
||||
public override string GetDate()
|
||||
{
|
||||
return "NOW()";
|
||||
}
|
||||
public override string GetRandom()
|
||||
{
|
||||
return "RANDOM()";
|
||||
}
|
||||
|
||||
public override string EqualTrue(string fieldName)
|
||||
{
|
||||
return "( " + fieldName + "=true )";
|
||||
}
|
||||
|
||||
public override string JsonField(MethodCallExpressionModel model)
|
||||
{
|
||||
var parameter = model.Args[0];
|
||||
var parameter1 = model.Args[1];
|
||||
//var parameter2 = model.Args[2];
|
||||
//var parameter3= model.Args[3];
|
||||
var result= GetJson(parameter.MemberName, parameter1.MemberName, model.Args.Count()==2);
|
||||
if (model.Args.Count > 2)
|
||||
{
|
||||
result = GetJson(result, model.Args[2].MemberName, model.Args.Count() == 3);
|
||||
}
|
||||
if (model.Args.Count > 3)
|
||||
{
|
||||
result = GetJson(result, model.Args[3].MemberName, model.Args.Count() == 4);
|
||||
}
|
||||
if (model.Args.Count > 4)
|
||||
{
|
||||
result = GetJson(result, model.Args[4].MemberName, model.Args.Count() == 5);
|
||||
}
|
||||
if (model.Args.Count > 5)
|
||||
{
|
||||
result = GetJson(result, model.Args[5].MemberName, model.Args.Count() == 6);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public override string JsonContainsFieldName(MethodCallExpressionModel model)
|
||||
{
|
||||
var parameter = model.Args[0];
|
||||
var parameter1 = model.Args[1];
|
||||
return $"({parameter.MemberName}::jsonb ?{parameter1.MemberName})";
|
||||
}
|
||||
|
||||
private string GetJson(object memberName1, object memberName2,bool isLast)
|
||||
{
|
||||
if (isLast)
|
||||
{
|
||||
return $"({memberName1}::json->>{memberName2})";
|
||||
}
|
||||
else
|
||||
{
|
||||
return $"({memberName1}->{memberName2})";
|
||||
}
|
||||
}
|
||||
|
||||
public override string JsonArrayLength(MethodCallExpressionModel model)
|
||||
{
|
||||
var parameter = model.Args[0];
|
||||
//var parameter1 = model.Args[1];
|
||||
return $" json_array_length({parameter.MemberName}::json) ";
|
||||
}
|
||||
|
||||
public override string JsonParse(MethodCallExpressionModel model)
|
||||
{
|
||||
var parameter = model.Args[0];
|
||||
//var parameter1 = model.Args[1];
|
||||
return $" ({parameter.MemberName}::json) ";
|
||||
}
|
||||
|
||||
public override string JsonArrayAny(MethodCallExpressionModel model)
|
||||
{
|
||||
if (SqlSugar.UtilMethods.IsNumber(model.Args[1].MemberValue.GetType().Name))
|
||||
{
|
||||
return $" {model.Args[0].MemberName}::jsonb @> '[{model.Args[1].MemberValue.ObjToStringNoTrim().ToSqlFilter()}]'::jsonb";
|
||||
}
|
||||
else
|
||||
{
|
||||
return $" {model.Args[0].MemberName}::jsonb @> '[\"{model.Args[1].MemberValue}\"]'::jsonb";
|
||||
}
|
||||
}
|
||||
public override string JsonListObjectAny(MethodCallExpressionModel model)
|
||||
{
|
||||
if (SqlSugar.UtilMethods.IsNumber(model.Args[2].MemberValue.GetType().Name))
|
||||
{
|
||||
return $" {model.Args[0].MemberName}::jsonb @> '[{{\"{model.Args[1].MemberValue}\":{model.Args[2].MemberValue}}}]'::jsonb";
|
||||
}
|
||||
else
|
||||
{
|
||||
return $" {model.Args[0].MemberName}::jsonb @> '[{{\"{model.Args[1].MemberValue}\":\"{model.Args[2].MemberValue.ObjToStringNoTrim().ToSqlFilter()}\"}}]'::jsonb";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using DuckDB;
|
||||
using DuckDB.NET.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SqlSugar.DuckDB
|
||||
{
|
||||
public class DuckDBFastBuilder : FastBuilder, IFastBuilder
|
||||
{
|
||||
public Task<int> ExecuteBulkCopyAsync(DataTable dt)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace SqlSugar.DuckDB
|
||||
{
|
||||
public class DuckDBInsertBuilder : InsertBuilder
|
||||
{
|
||||
public override string SqlTemplate
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsReturnIdentity)
|
||||
{
|
||||
return @"INSERT INTO {0}
|
||||
({1})
|
||||
VALUES
|
||||
({2}) returning $PrimaryKey";
|
||||
}
|
||||
else
|
||||
{
|
||||
return @"INSERT INTO {0}
|
||||
({1})
|
||||
VALUES
|
||||
({2}) ;";
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
public override string SqlTemplateBatch => "INSERT INTO {0} ({1})";
|
||||
public override string SqlTemplateBatchUnion => " VALUES ";
|
||||
|
||||
public override string SqlTemplateBatchSelect => " {0} ";
|
||||
|
||||
public override Func<string, string, string> ConvertInsertReturnIdFunc { get; set; } = (name, sql) =>
|
||||
{
|
||||
return sql.Trim().TrimEnd(';')+ $"returning {name} ";
|
||||
};
|
||||
public override string ToSqlString()
|
||||
{
|
||||
if (IsNoInsertNull)
|
||||
{
|
||||
DbColumnInfoList = DbColumnInfoList.Where(it => it.Value != null).ToList();
|
||||
}
|
||||
var groupList = DbColumnInfoList.GroupBy(it => it.TableId).ToList();
|
||||
var isSingle = groupList.Count() == 1;
|
||||
string columnsString = string.Join(",", groupList.First().Select(it => Builder.GetTranslationColumnName(it.DbColumnName)));
|
||||
if (isSingle)
|
||||
{
|
||||
string columnParametersString = string.Join(",", this.DbColumnInfoList.Select(it =>base.GetDbColumn(it, Builder.SqlParameterKeyWord + it.DbColumnName)));
|
||||
ActionMinDate();
|
||||
return string.Format(SqlTemplate, GetTableNameString, columnsString, columnParametersString);
|
||||
}
|
||||
else
|
||||
{
|
||||
StringBuilder batchInsetrSql = new StringBuilder();
|
||||
int pageSize = 200;
|
||||
int pageIndex = 1;
|
||||
if (IsNoPage&&IsReturnPkList)
|
||||
{
|
||||
pageSize = groupList.Count;
|
||||
}
|
||||
int totalRecord = groupList.Count;
|
||||
int pageCount = (totalRecord + pageSize - 1) / pageSize;
|
||||
while (pageCount >= pageIndex)
|
||||
{
|
||||
batchInsetrSql.AppendFormat(SqlTemplateBatch, GetTableNameString, columnsString);
|
||||
int i = 0;
|
||||
foreach (var columns in groupList.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList())
|
||||
{
|
||||
var isFirst = i == 0;
|
||||
if (isFirst)
|
||||
{
|
||||
batchInsetrSql.Append(SqlTemplateBatchUnion);
|
||||
}
|
||||
batchInsetrSql.Append("\r\n ( " + string.Join(",", columns.Select(it =>
|
||||
{
|
||||
if (it.InsertServerTime || it.InsertSql.HasValue()||it.SqlParameterDbType is Type|| it?.PropertyType?.Name=="DateOnly" || it?.PropertyType?.Name == "TimeOnly")
|
||||
{
|
||||
return GetDbColumn(it, null);
|
||||
}
|
||||
object value = null;
|
||||
if (it.Value is DateTime)
|
||||
{
|
||||
value = ((DateTime)it.Value).ToString("O");
|
||||
}
|
||||
else if (it.Value is DateTimeOffset)
|
||||
{
|
||||
return FormatDateTimeOffset(it.Value);
|
||||
}
|
||||
else if (it.IsArray&&it.Value!=null)
|
||||
{
|
||||
return FormatValue(it.Value,it.PropertyName,i,it);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = it.Value;
|
||||
}
|
||||
if (value == null||value==DBNull.Value)
|
||||
{
|
||||
return string.Format(SqlTemplateBatchSelect, "NULL");
|
||||
}
|
||||
return string.Format(SqlTemplateBatchSelect, "'" + value.ObjToStringNoTrim().ToSqlFilter() + "'");
|
||||
})) + "),");
|
||||
++i;
|
||||
}
|
||||
pageIndex++;
|
||||
batchInsetrSql.Remove(batchInsetrSql.Length - 1,1).Append("\r\n;\r\n");
|
||||
}
|
||||
return batchInsetrSql.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public object FormatValue(object value, string name, int i, DbColumnInfo columnInfo)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return "NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
var type = value.GetType();
|
||||
if (type == UtilConstants.DateType || columnInfo.IsArray || columnInfo.IsJson)
|
||||
{
|
||||
var parameterName = this.Builder.SqlParameterKeyWord + name + i;
|
||||
var paramter = new SugarParameter(parameterName, value);
|
||||
if (columnInfo.IsJson)
|
||||
{
|
||||
paramter.IsJson = true;
|
||||
}
|
||||
if (columnInfo.IsArray)
|
||||
{
|
||||
paramter.IsArray = true;
|
||||
}
|
||||
this.Parameters.Add(paramter);
|
||||
return parameterName;
|
||||
}
|
||||
else if (type == UtilConstants.ByteArrayType)
|
||||
{
|
||||
string bytesString = "0x" + BitConverter.ToString((byte[])value);
|
||||
return bytesString;
|
||||
}
|
||||
else if (type.IsEnum())
|
||||
{
|
||||
if (this.Context.CurrentConnectionConfig.MoreSettings?.TableEnumIsString == true)
|
||||
{
|
||||
return value.ToSqlValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
return Convert.ToInt64(value);
|
||||
}
|
||||
}
|
||||
else if (type == UtilConstants.DateTimeOffsetType)
|
||||
{
|
||||
return FormatDateTimeOffset(value);
|
||||
}
|
||||
else if (type == UtilConstants.BoolType)
|
||||
{
|
||||
return value.ObjToBool() ? "1" : "0";
|
||||
}
|
||||
else if (type == UtilConstants.StringType || type == UtilConstants.ObjType)
|
||||
{
|
||||
return "'" + value.ToString().ToSqlFilter() + "'";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "'" + value.ToString() + "'";
|
||||
}
|
||||
}
|
||||
}
|
||||
public override string FormatDateTimeOffset(object value)
|
||||
{
|
||||
return "'" + ((DateTimeOffset)value).ToString("o") + "'";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace SqlSugar.DuckDB
|
||||
{
|
||||
public partial class DuckDBQueryBuilder : QueryBuilder
|
||||
{
|
||||
#region Sql Template
|
||||
public override string PageTempalte
|
||||
{
|
||||
get
|
||||
{
|
||||
/*
|
||||
SELECT * FROM TABLE WHERE CONDITION ORDER BY ID DESC LIMIT 10 offset 0
|
||||
*/
|
||||
var template = "SELECT {0} FROM {1} {2} {3} {4} LIMIT {6} offset {5}";
|
||||
return template;
|
||||
}
|
||||
}
|
||||
public override string DefaultOrderByTemplate
|
||||
{
|
||||
get
|
||||
{
|
||||
return "ORDER BY NOW() ";
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Common Methods
|
||||
public override string GetTableNameString
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.TableShortName != null&&this.Context.CurrentConnectionConfig?.MoreSettings?.PgSqlIsAutoToLower==false)
|
||||
{
|
||||
this.TableShortName = Builder.GetTranslationColumnName(this.TableShortName);
|
||||
}
|
||||
return base.GetTableNameString;
|
||||
}
|
||||
}
|
||||
public override bool IsComplexModel(string sql)
|
||||
{
|
||||
return Regex.IsMatch(sql, @"AS ""\w+\.\w+""")|| Regex.IsMatch(sql, @"AS ""\w+\.\w+\.\w+""");
|
||||
}
|
||||
public override string ToSqlString()
|
||||
{
|
||||
base.AppendFilter();
|
||||
string oldOrderValue = this.OrderByValue;
|
||||
string result = null;
|
||||
sql = new StringBuilder();
|
||||
sql.AppendFormat(SqlTemplate, GetSelectValue, GetTableNameString, GetWhereValueString, GetGroupByString + HavingInfos, (Skip != null || Take != null) ? null : GetOrderByString);
|
||||
if (IsCount) { return sql.ToString(); }
|
||||
if (Skip != null && Take == null)
|
||||
{
|
||||
if (this.OrderByValue == "ORDER BY ") this.OrderByValue += GetSelectValue.Split(',')[0];
|
||||
result = string.Format(PageTempalte, GetSelectValue, GetTableNameString, GetWhereValueString, GetGroupByString + HavingInfos, (Skip != null || Take != null) ? null : GetOrderByString, Skip.ObjToInt(), long.MaxValue);
|
||||
}
|
||||
else if (Skip == null && Take != null)
|
||||
{
|
||||
if (this.OrderByValue == "ORDER BY ") this.OrderByValue += GetSelectValue.Split(',')[0];
|
||||
result = string.Format(PageTempalte, GetSelectValue, GetTableNameString, GetWhereValueString, GetGroupByString + HavingInfos, GetOrderByString, 0, Take.ObjToInt());
|
||||
}
|
||||
else if (Skip != null && Take != null)
|
||||
{
|
||||
if (this.OrderByValue == "ORDER BY ") this.OrderByValue += GetSelectValue.Split(',')[0];
|
||||
result = string.Format(PageTempalte, GetSelectValue, GetTableNameString, GetWhereValueString, GetGroupByString + HavingInfos, GetOrderByString, Skip.ObjToInt() > 0 ? Skip.ObjToInt() : 0, Take);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = sql.ToString();
|
||||
}
|
||||
this.OrderByValue = oldOrderValue;
|
||||
result = GetSqlQuerySql(result);
|
||||
if (result.IndexOf("-- No table") > 0)
|
||||
{
|
||||
return "-- No table";
|
||||
}
|
||||
if (TranLock != null)
|
||||
{
|
||||
result = result + TranLock;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Get SQL Partial
|
||||
public override string GetSelectValue
|
||||
{
|
||||
get
|
||||
{
|
||||
string result = string.Empty;
|
||||
if (this.SelectValue == null || this.SelectValue is string)
|
||||
{
|
||||
result = GetSelectValueByString();
|
||||
}
|
||||
else
|
||||
{
|
||||
result = GetSelectValueByExpression();
|
||||
}
|
||||
if (this.SelectType == ResolveExpressType.SelectMultiple)
|
||||
{
|
||||
this.SelectCacheKey = this.SelectCacheKey + string.Join("-", this.JoinQueryInfos.Select(it => it.TableName));
|
||||
}
|
||||
if (IsDistinct)
|
||||
{
|
||||
result = "distinct "+result;
|
||||
}
|
||||
if (this.SubToListParameters != null && this.SubToListParameters.Any())
|
||||
{
|
||||
result = SubToListMethod(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,249 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace SqlSugar.DuckDB
|
||||
{
|
||||
public class DuckDBUpdateBuilder : UpdateBuilder
|
||||
{
|
||||
public override string SqlTemplateBatch
|
||||
{
|
||||
get
|
||||
{
|
||||
return @"UPDATE {1} {2} SET {0} FROM ${{0}} ";
|
||||
}
|
||||
}
|
||||
public override string SqlTemplateJoin
|
||||
{
|
||||
get
|
||||
{
|
||||
return @" (VALUES
|
||||
{0}
|
||||
|
||||
) AS T ({2}) WHERE {1}
|
||||
";
|
||||
}
|
||||
}
|
||||
|
||||
public override string SqlTemplateBatchUnion
|
||||
{
|
||||
get
|
||||
{
|
||||
return ",";
|
||||
}
|
||||
}
|
||||
|
||||
public object FormatValue(object value,string name,int i,DbColumnInfo columnInfo)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return "NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
var type =UtilMethods.GetUnderType(value.GetType());
|
||||
if (type == UtilConstants.DateType||columnInfo.IsArray||columnInfo.IsJson)
|
||||
{
|
||||
var parameterName = this.Builder.SqlParameterKeyWord + name + i;
|
||||
var paramter = new SugarParameter(parameterName, value);
|
||||
if (columnInfo.IsJson)
|
||||
{
|
||||
paramter.IsJson = true;
|
||||
}
|
||||
if (columnInfo.IsArray)
|
||||
{
|
||||
paramter.IsArray = true;
|
||||
}
|
||||
this.Parameters.Add(paramter);
|
||||
return parameterName;
|
||||
}
|
||||
else if (type == UtilConstants.DateTimeOffsetType)
|
||||
{
|
||||
return FormatDateTimeOffset(value);
|
||||
}
|
||||
else if (type == UtilConstants.ByteArrayType)
|
||||
{
|
||||
string bytesString = "0x" + BitConverter.ToString((byte[])value);
|
||||
return bytesString;
|
||||
}
|
||||
else if (type.IsEnum())
|
||||
{
|
||||
if (this.Context.CurrentConnectionConfig.MoreSettings?.TableEnumIsString == true)
|
||||
{
|
||||
return value.ToSqlValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
return Convert.ToInt64(value);
|
||||
}
|
||||
}
|
||||
else if (type == UtilConstants.BoolType)
|
||||
{
|
||||
return value.ObjToBool() ? "1" : "0";
|
||||
}
|
||||
else if (type == UtilConstants.StringType || type == UtilConstants.ObjType)
|
||||
{
|
||||
return "'" + value.ToString().ToSqlFilter() + "'";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "'" + value.ToString() + "'";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override string TomultipleSqlString(List<IGrouping<int, DbColumnInfo>> groupList)
|
||||
{
|
||||
Check.Exception(PrimaryKeys == null || PrimaryKeys.Count == 0, " Update List<T> need Primary key");
|
||||
int pageSize = 200;
|
||||
int pageIndex = 1;
|
||||
int totalRecord = groupList.Count;
|
||||
int pageCount = (totalRecord + pageSize - 1) / pageSize;
|
||||
StringBuilder batchUpdateSql = new StringBuilder();
|
||||
while (pageCount >= pageIndex)
|
||||
{
|
||||
StringBuilder updateTable = new StringBuilder();
|
||||
string setValues = string.Join(",", groupList.First().Where(it => it.IsPrimarykey == false && (it.IsIdentity == false || (IsOffIdentity && it.IsIdentity))).Select(it =>
|
||||
{
|
||||
if (SetValues.IsValuable())
|
||||
{
|
||||
var setValue = SetValues.Where(sv => sv.Key == Builder.GetTranslationColumnName(it.DbColumnName));
|
||||
if (setValue != null && setValue.Any())
|
||||
{
|
||||
return setValue.First().Value;
|
||||
}
|
||||
}
|
||||
var result = string.Format("{0}=T.{0}", Builder.GetTranslationColumnName(it.DbColumnName));
|
||||
return result;
|
||||
}));
|
||||
string tempColumnValue = string.Join(",", groupList.First().Select(it =>
|
||||
{
|
||||
if (SetValues.IsValuable())
|
||||
{
|
||||
var setValue = SetValues.Where(sv => sv.Key == Builder.GetTranslationColumnName(it.DbColumnName));
|
||||
if (setValue != null && setValue.Any())
|
||||
{
|
||||
return setValue.First().Value;
|
||||
}
|
||||
}
|
||||
var result = Builder.GetTranslationColumnName(it.DbColumnName);
|
||||
return result;
|
||||
}));
|
||||
batchUpdateSql.AppendFormat(SqlTemplateBatch.ToString(), setValues, GetTableNameStringNoWith, TableWithString);
|
||||
int i = 0;
|
||||
var tableColumnList = this.Context.DbMaintenance.GetColumnInfosByTableName(GetTableNameStringNoWith);
|
||||
|
||||
foreach (var columns in groupList.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList())
|
||||
{
|
||||
var isFirst = i == 0;
|
||||
if (!isFirst)
|
||||
{
|
||||
updateTable.Append(SqlTemplateBatchUnion);
|
||||
}
|
||||
updateTable.Append("\r\n (" + string.Join(",", columns.Select(it =>
|
||||
{
|
||||
var columnInfo = tableColumnList.FirstOrDefault(x => x.DbColumnName.Equals(it.DbColumnName, StringComparison.OrdinalIgnoreCase));
|
||||
var dbType = columnInfo?.DataType;
|
||||
if (dbType == null) {
|
||||
var typeName = it.PropertyType.Name.ToLower();
|
||||
if (columnInfo==null&&it.PropertyType.IsEnum)
|
||||
{
|
||||
if (this.Context.CurrentConnectionConfig?.MoreSettings?.TableEnumIsString!=true)
|
||||
{
|
||||
typeName = "int";
|
||||
}
|
||||
}
|
||||
if (typeName == "int32")
|
||||
typeName = "int";
|
||||
if (typeName == "int64")
|
||||
typeName = "long";
|
||||
if (typeName == "int16")
|
||||
typeName = "short";
|
||||
if (typeName == "boolean")
|
||||
typeName = "bool";
|
||||
|
||||
var isAnyType = DuckDBDbBind.MappingTypesConst.Where(x => x.Value.ToString().ToLower() == typeName).Any();
|
||||
if (isAnyType)
|
||||
{
|
||||
dbType = DuckDBDbBind.MappingTypesConst.Where(x => x.Value.ToString().ToLower() == typeName).FirstOrDefault().Key;
|
||||
}
|
||||
else {
|
||||
dbType = "varchar";
|
||||
}
|
||||
}
|
||||
return string.Format("CAST({0} AS {1})", base.GetDbColumn(it,FormatValue(it.Value,it.DbColumnName,i,it)), dbType);
|
||||
|
||||
})) + ")");
|
||||
++i;
|
||||
}
|
||||
pageIndex++;
|
||||
updateTable.Append("\r\n");
|
||||
string whereString = null;
|
||||
if (this.WhereValues.HasValue())
|
||||
{
|
||||
foreach (var item in WhereValues)
|
||||
{
|
||||
var isFirst = whereString == null;
|
||||
whereString += (isFirst ? null : " AND ");
|
||||
whereString += item;
|
||||
}
|
||||
}
|
||||
else if (PrimaryKeys.HasValue())
|
||||
{
|
||||
foreach (var item in PrimaryKeys)
|
||||
{
|
||||
var isFirst = whereString == null;
|
||||
whereString += (isFirst ? null : " AND ");
|
||||
whereString += string.Format("{0}.{1}=T.{1}", GetTableNameStringNoWith, Builder.GetTranslationColumnName(item));
|
||||
}
|
||||
}
|
||||
var format = string.Format(SqlTemplateJoin, updateTable, whereString, tempColumnValue);
|
||||
batchUpdateSql.Replace("${0}", format);
|
||||
batchUpdateSql.Append(";");
|
||||
}
|
||||
batchUpdateSql = GetBatchUpdateSql(batchUpdateSql);
|
||||
return batchUpdateSql.ToString();
|
||||
}
|
||||
|
||||
private StringBuilder GetBatchUpdateSql(StringBuilder batchUpdateSql)
|
||||
{
|
||||
if (ReSetValueBySqlExpListType == null && ReSetValueBySqlExpList != null)
|
||||
{
|
||||
var result = batchUpdateSql.ToString();
|
||||
foreach (var item in ReSetValueBySqlExpList)
|
||||
{
|
||||
var dbColumnName = item.Value.DbColumnName;
|
||||
if (item.Value.Type == ReSetValueBySqlExpListModelType.List)
|
||||
{
|
||||
result = result.Replace($"{dbColumnName}=T.{dbColumnName}", $"{dbColumnName}={GetTableNameString}.{dbColumnName}{item.Value.Sql}T.{dbColumnName}");
|
||||
}
|
||||
else
|
||||
{
|
||||
result = result.Replace($"{dbColumnName}=T.{dbColumnName}", $"{dbColumnName}={item.Value.Sql.Replace(dbColumnName, $"{Builder.GetTranslationColumnName(this.TableName)}.{dbColumnName}")}");
|
||||
}
|
||||
batchUpdateSql = new StringBuilder(result);
|
||||
}
|
||||
}
|
||||
|
||||
return batchUpdateSql;
|
||||
}
|
||||
protected override string GetJoinUpdate(string columnsString, ref string whereString)
|
||||
{
|
||||
var formString = $" {Builder.GetTranslationColumnName(this.TableName)} AS {Builder.GetTranslationColumnName(this.ShortName)} ";
|
||||
var joinString = "";
|
||||
foreach (var item in this.JoinInfos)
|
||||
{
|
||||
whereString += " AND "+item.JoinWhere;
|
||||
joinString += $"\r\n FROM {Builder.GetTranslationColumnName(item.TableName)} {Builder.GetTranslationColumnName(item.ShortName)} ";
|
||||
}
|
||||
var tableName = formString + "\r\n ";
|
||||
columnsString = columnsString.Replace(Builder.GetTranslationColumnName(this.ShortName)+".","")+joinString;
|
||||
return string.Format(SqlTemplate, tableName, columnsString, whereString);
|
||||
}
|
||||
public override string FormatDateTimeOffset(object value)
|
||||
{
|
||||
return "'" + ((DateTimeOffset)value).ToString("o") + "'";
|
||||
}
|
||||
}
|
||||
}
|
||||
144
Src/Asp.NetCore2/SqlSugar.DuckDBCore/DuckDBDataAdapter.cs
Normal file
144
Src/Asp.NetCore2/SqlSugar.DuckDBCore/DuckDBDataAdapter.cs
Normal file
@@ -0,0 +1,144 @@
|
||||
using DuckDB;
|
||||
using DuckDB.NET.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Text;
|
||||
|
||||
namespace SqlSugar
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据填充器
|
||||
/// </summary>
|
||||
public class DuckDBDataAdapter : IDataAdapter
|
||||
{
|
||||
private DuckDBCommand command;
|
||||
private string sql;
|
||||
private DuckDBConnection _sqlConnection;
|
||||
|
||||
/// <summary>
|
||||
/// SqlDataAdapter
|
||||
/// </summary>
|
||||
/// <param name="command"></param>
|
||||
public DuckDBDataAdapter(DuckDBCommand command)
|
||||
{
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
public DuckDBDataAdapter()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// SqlDataAdapter
|
||||
/// </summary>
|
||||
/// <param name="sql"></param>
|
||||
/// <param name="_sqlConnection"></param>
|
||||
public DuckDBDataAdapter(string sql, DuckDBConnection _sqlConnection)
|
||||
{
|
||||
this.sql = sql;
|
||||
this._sqlConnection = _sqlConnection;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// SelectCommand
|
||||
/// </summary>
|
||||
public DuckDBCommand SelectCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.command == null)
|
||||
{
|
||||
this.command = new DuckDBCommand(this.sql, this._sqlConnection);
|
||||
}
|
||||
return this.command;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.command = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fill
|
||||
/// </summary>
|
||||
/// <param name="dt"></param>
|
||||
public void Fill(DataTable dt)
|
||||
{
|
||||
if (dt == null)
|
||||
{
|
||||
dt = new DataTable();
|
||||
}
|
||||
var columns = dt.Columns;
|
||||
var rows = dt.Rows;
|
||||
using (DuckDBDataReader dr = command.ExecuteReader())
|
||||
{
|
||||
for (int i = 0; i < dr.FieldCount; i++)
|
||||
{
|
||||
string name = dr.GetName(i).Trim();
|
||||
if (!columns.Contains(name))
|
||||
columns.Add(new DataColumn(name, dr.GetFieldType(i)));
|
||||
else
|
||||
{
|
||||
columns.Add(new DataColumn(name + i, dr.GetFieldType(i)));
|
||||
}
|
||||
}
|
||||
|
||||
while (dr.Read())
|
||||
{
|
||||
DataRow daRow = dt.NewRow();
|
||||
for (int i = 0; i < columns.Count; i++)
|
||||
{
|
||||
daRow[columns[i].ColumnName] = dr.GetValue(i);
|
||||
}
|
||||
dt.Rows.Add(daRow);
|
||||
}
|
||||
}
|
||||
dt.AcceptChanges();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fill
|
||||
/// </summary>
|
||||
/// <param name="ds"></param>
|
||||
public void Fill(DataSet ds)
|
||||
{
|
||||
if (ds == null)
|
||||
{
|
||||
ds = new DataSet();
|
||||
}
|
||||
using (DuckDBDataReader dr = command.ExecuteReader())
|
||||
{
|
||||
do
|
||||
{
|
||||
var dt = new DataTable();
|
||||
var columns = dt.Columns;
|
||||
var rows = dt.Rows;
|
||||
for (int i = 0; i < dr.FieldCount; i++)
|
||||
{
|
||||
string name = dr.GetName(i).Trim();
|
||||
if (!columns.Contains(name))
|
||||
columns.Add(new DataColumn(name, dr.GetFieldType(i)));
|
||||
else
|
||||
{
|
||||
columns.Add(new DataColumn(name + i, dr.GetFieldType(i)));
|
||||
}
|
||||
}
|
||||
|
||||
while (dr.Read())
|
||||
{
|
||||
DataRow daRow = dt.NewRow();
|
||||
for (int i = 0; i < columns.Count; i++)
|
||||
{
|
||||
daRow[columns[i].ColumnName] = dr.GetValue(i);
|
||||
}
|
||||
dt.Rows.Add(daRow);
|
||||
}
|
||||
dt.AcceptChanges();
|
||||
ds.Tables.Add(dt);
|
||||
} while (dr.NextResult());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="DuckDB.NET.Data.Full" Version="1.2.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SqlSugar\SqlSugar.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
64
Src/Asp.NetCore2/SqlSugar.DuckDBCore/Tools/ErrorMessage.cs
Normal file
64
Src/Asp.NetCore2/SqlSugar.DuckDBCore/Tools/ErrorMessage.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
namespace SqlSugar.DuckDB
|
||||
{
|
||||
internal static partial class ErrorMessage
|
||||
{
|
||||
internal static LanguageType SugarLanguageType { get; set; } = LanguageType.Default;
|
||||
internal static string ObjNotExist
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetThrowMessage("{0} does not exist.",
|
||||
"{0}不存在。");
|
||||
}
|
||||
}
|
||||
internal static string EntityMappingError
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetThrowMessage("Entity mapping error.{0}",
|
||||
"实体与表映射出错。{0}");
|
||||
}
|
||||
}
|
||||
|
||||
public static string NotSupportedDictionary
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetThrowMessage("This type of Dictionary is not supported for the time being. You can try Dictionary<string, string>, or contact the author!!",
|
||||
"暂时不支持该类型的Dictionary 你可以试试 Dictionary<string ,string>或者联系作者!!");
|
||||
}
|
||||
}
|
||||
|
||||
public static string NotSupportedArray
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetThrowMessage("This type of Array is not supported for the time being. You can try object[] or contact the author!!",
|
||||
"暂时不支持该类型的Array 你可以试试 object[] 或者联系作者!!");
|
||||
}
|
||||
}
|
||||
|
||||
internal static string GetThrowMessage(string enMessage, string cnMessage, params string[] args)
|
||||
{
|
||||
if (SugarLanguageType == LanguageType.Default)
|
||||
{
|
||||
List<string> formatArgs = new List<string>() { enMessage, cnMessage };
|
||||
formatArgs.AddRange(args);
|
||||
return string.Format(@"中文提示 : {1}
|
||||
English Message : {0}", formatArgs.ToArray());
|
||||
}
|
||||
else if (SugarLanguageType == LanguageType.English)
|
||||
{
|
||||
return enMessage;
|
||||
}
|
||||
else
|
||||
{
|
||||
return cnMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
70
Src/Asp.NetCore2/SqlSugar.DuckDBCore/Tools/FileHelper.cs
Normal file
70
Src/Asp.NetCore2/SqlSugar.DuckDBCore/Tools/FileHelper.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace SqlSugar.DuckDB
|
||||
{
|
||||
internal class FileHelper
|
||||
{
|
||||
public static void CreateFile(string filePath, string text, Encoding encoding)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (IsExistFile(filePath))
|
||||
{
|
||||
DeleteFile(filePath);
|
||||
}
|
||||
if (!IsExistFile(filePath))
|
||||
{
|
||||
string directoryPath = GetDirectoryFromFilePath(filePath);
|
||||
CreateDirectory(directoryPath);
|
||||
|
||||
//Create File
|
||||
FileInfo file = new FileInfo(filePath);
|
||||
using (FileStream stream = file.Create())
|
||||
{
|
||||
using (StreamWriter writer = new StreamWriter(stream, encoding))
|
||||
{
|
||||
writer.Write(text);
|
||||
writer.Flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
public static bool IsExistDirectory(string directoryPath)
|
||||
{
|
||||
return Directory.Exists(directoryPath);
|
||||
}
|
||||
public static void CreateDirectory(string directoryPath)
|
||||
{
|
||||
if (!IsExistDirectory(directoryPath))
|
||||
{
|
||||
Directory.CreateDirectory(directoryPath);
|
||||
}
|
||||
}
|
||||
public static void DeleteFile(string filePath)
|
||||
{
|
||||
if (IsExistFile(filePath))
|
||||
{
|
||||
File.Delete(filePath);
|
||||
}
|
||||
}
|
||||
public static string GetDirectoryFromFilePath(string filePath)
|
||||
{
|
||||
FileInfo file = new FileInfo(filePath);
|
||||
DirectoryInfo directory = file.Directory;
|
||||
return directory.FullName;
|
||||
}
|
||||
public static bool IsExistFile(string filePath)
|
||||
{
|
||||
return File.Exists(filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
73
Src/Asp.NetCore2/SqlSugar.DuckDBCore/Tools/UtilConstants.cs
Normal file
73
Src/Asp.NetCore2/SqlSugar.DuckDBCore/Tools/UtilConstants.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Dynamic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
namespace SqlSugar.DuckDB
|
||||
{
|
||||
internal static class UtilConstants
|
||||
{
|
||||
public const string Dot = ".";
|
||||
public const char DotChar = '.';
|
||||
internal const string Space = " ";
|
||||
internal const char SpaceChar =' ';
|
||||
internal const string AssemblyName = "SqlSugar";
|
||||
internal const string ReplaceKey = "{662E689B-17A1-4D06-9D27-F29EAB8BC3D6}";
|
||||
internal const string ReplaceCommaKey = "{112A689B-17A1-4A06-9D27-A39EAB8BC3D5}";
|
||||
|
||||
internal static Type IntType = typeof(int);
|
||||
internal static Type LongType = typeof(long);
|
||||
internal static Type GuidType = typeof(Guid);
|
||||
internal static Type BoolType = typeof(bool);
|
||||
internal static Type BoolTypeNull = typeof(bool?);
|
||||
internal static Type ByteType = typeof(Byte);
|
||||
internal static Type ObjType = typeof(object);
|
||||
internal static Type DobType = typeof(double);
|
||||
internal static Type FloatType = typeof(float);
|
||||
internal static Type ShortType = typeof(short);
|
||||
internal static Type DecType = typeof(decimal);
|
||||
internal static Type StringType = typeof(string);
|
||||
internal static Type DateType = typeof(DateTime);
|
||||
internal static Type DateTimeOffsetType = typeof(DateTimeOffset);
|
||||
internal static Type TimeSpanType = typeof(TimeSpan);
|
||||
internal static Type ByteArrayType = typeof(byte[]);
|
||||
internal static Type ModelType= typeof(ModelContext);
|
||||
internal static Type DynamicType = typeof(ExpandoObject);
|
||||
internal static Type Dicii = typeof(KeyValuePair<int, int>);
|
||||
internal static Type DicIS = typeof(KeyValuePair<int, string>);
|
||||
internal static Type DicSi = typeof(KeyValuePair<string, int>);
|
||||
internal static Type DicSS = typeof(KeyValuePair<string, string>);
|
||||
internal static Type DicOO = typeof(KeyValuePair<object, object>);
|
||||
internal static Type DicSo = typeof(KeyValuePair<string, object>);
|
||||
internal static Type DicArraySS = typeof(Dictionary<string, string>);
|
||||
internal static Type DicArraySO = typeof(Dictionary<string, object>);
|
||||
|
||||
public static Type SugarType = typeof(SqlSugarProvider);
|
||||
|
||||
|
||||
internal static Type[] NumericalTypes = new Type[]
|
||||
{
|
||||
typeof(int),
|
||||
typeof(uint),
|
||||
typeof(byte),
|
||||
typeof(sbyte),
|
||||
typeof(long),
|
||||
typeof(ulong),
|
||||
typeof(short),
|
||||
typeof(ushort),
|
||||
};
|
||||
|
||||
|
||||
internal static string[] DateTypeStringList = new string[]
|
||||
{
|
||||
"Year",
|
||||
"Month",
|
||||
"Day",
|
||||
"Hour",
|
||||
"Second" ,
|
||||
"Minute",
|
||||
"Millisecond",
|
||||
"Date"
|
||||
};
|
||||
}
|
||||
}
|
||||
136
Src/Asp.NetCore2/SqlSugar.DuckDBCore/Tools/UtilExtensions.cs
Normal file
136
Src/Asp.NetCore2/SqlSugar.DuckDBCore/Tools/UtilExtensions.cs
Normal file
@@ -0,0 +1,136 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
namespace SqlSugar.DuckDB
|
||||
{
|
||||
/// <summary>
|
||||
///Common Extensions for external users
|
||||
/// </summary>
|
||||
public static class UtilExtensions
|
||||
{
|
||||
public static string ObjToStringNoTrim(this object thisValue)
|
||||
{
|
||||
if (thisValue != null) return thisValue.ToString();
|
||||
return "";
|
||||
}
|
||||
public static string ToLower(this string value, bool isLower)
|
||||
{
|
||||
if (isLower)
|
||||
{
|
||||
return value.ObjToString().ToLower();
|
||||
}
|
||||
return value.ObjToString();
|
||||
}
|
||||
public static int ObjToInt(this object thisValue)
|
||||
{
|
||||
int reval = 0;
|
||||
if (thisValue == null) return 0;
|
||||
if (thisValue is Enum)
|
||||
{
|
||||
return (int)thisValue;
|
||||
}
|
||||
if (thisValue != null && thisValue != DBNull.Value && int.TryParse(thisValue.ToString(), out reval))
|
||||
{
|
||||
return reval;
|
||||
}
|
||||
return reval;
|
||||
}
|
||||
|
||||
public static int ObjToInt(this object thisValue, int errorValue)
|
||||
{
|
||||
int reval = 0;
|
||||
if (thisValue is Enum)
|
||||
{
|
||||
return (int)thisValue;
|
||||
}
|
||||
if (thisValue != null && thisValue != DBNull.Value && int.TryParse(thisValue.ToString(), out reval))
|
||||
{
|
||||
return reval;
|
||||
}
|
||||
return errorValue;
|
||||
}
|
||||
|
||||
public static double ObjToMoney(this object thisValue)
|
||||
{
|
||||
double reval = 0;
|
||||
if (thisValue != null && thisValue != DBNull.Value && double.TryParse(thisValue.ToString(), out reval))
|
||||
{
|
||||
return reval;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static double ObjToMoney(this object thisValue, double errorValue)
|
||||
{
|
||||
double reval = 0;
|
||||
if (thisValue != null && thisValue != DBNull.Value && double.TryParse(thisValue.ToString(), out reval))
|
||||
{
|
||||
return reval;
|
||||
}
|
||||
return errorValue;
|
||||
}
|
||||
|
||||
public static string ObjToString(this object thisValue)
|
||||
{
|
||||
if (thisValue != null) return thisValue.ToString().Trim();
|
||||
return "";
|
||||
}
|
||||
|
||||
public static string ObjToString(this object thisValue, string errorValue)
|
||||
{
|
||||
if (thisValue != null) return thisValue.ToString().Trim();
|
||||
return errorValue;
|
||||
}
|
||||
|
||||
public static Decimal ObjToDecimal(this object thisValue)
|
||||
{
|
||||
Decimal reval = 0;
|
||||
if (thisValue != null && thisValue != DBNull.Value && decimal.TryParse(thisValue.ToString(), out reval))
|
||||
{
|
||||
return reval;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static Decimal ObjToDecimal(this object thisValue, decimal errorValue)
|
||||
{
|
||||
Decimal reval = 0;
|
||||
if (thisValue != null && thisValue != DBNull.Value && decimal.TryParse(thisValue.ToString(), out reval))
|
||||
{
|
||||
return reval;
|
||||
}
|
||||
return errorValue;
|
||||
}
|
||||
|
||||
public static DateTime ObjToDate(this object thisValue)
|
||||
{
|
||||
DateTime reval = DateTime.MinValue;
|
||||
if (thisValue != null && thisValue != DBNull.Value && DateTime.TryParse(thisValue.ToString(), out reval))
|
||||
{
|
||||
reval = Convert.ToDateTime(thisValue);
|
||||
}
|
||||
return reval;
|
||||
}
|
||||
|
||||
public static DateTime ObjToDate(this object thisValue, DateTime errorValue)
|
||||
{
|
||||
DateTime reval = DateTime.MinValue;
|
||||
if (thisValue != null && thisValue != DBNull.Value && DateTime.TryParse(thisValue.ToString(), out reval))
|
||||
{
|
||||
return reval;
|
||||
}
|
||||
return errorValue;
|
||||
}
|
||||
|
||||
public static bool ObjToBool(this object thisValue)
|
||||
{
|
||||
bool reval = false;
|
||||
if (thisValue != null && thisValue != DBNull.Value && bool.TryParse(thisValue.ToString(), out reval))
|
||||
{
|
||||
return reval;
|
||||
}
|
||||
return reval;
|
||||
}
|
||||
}
|
||||
}
|
||||
507
Src/Asp.NetCore2/SqlSugar.DuckDBCore/Tools/UtilMethods.cs
Normal file
507
Src/Asp.NetCore2/SqlSugar.DuckDBCore/Tools/UtilMethods.cs
Normal file
@@ -0,0 +1,507 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace SqlSugar.DuckDB
|
||||
{
|
||||
public class UtilMethods
|
||||
{
|
||||
internal static DateTime GetMinDate(ConnectionConfig currentConnectionConfig)
|
||||
{
|
||||
if (currentConnectionConfig.MoreSettings == null)
|
||||
{
|
||||
return Convert.ToDateTime("1900-01-01");
|
||||
}
|
||||
else if (currentConnectionConfig.MoreSettings.DbMinDate == null)
|
||||
{
|
||||
return Convert.ToDateTime("1900-01-01");
|
||||
}
|
||||
else
|
||||
{
|
||||
return currentConnectionConfig.MoreSettings.DbMinDate.Value;
|
||||
}
|
||||
}
|
||||
internal static DateTime ConvertFromDateTimeOffset(DateTimeOffset dateTime)
|
||||
{
|
||||
if (dateTime.Offset.Equals(TimeSpan.Zero))
|
||||
return dateTime.UtcDateTime;
|
||||
else if (dateTime.Offset.Equals(TimeZoneInfo.Local.GetUtcOffset(dateTime.DateTime)))
|
||||
return DateTime.SpecifyKind(dateTime.DateTime, DateTimeKind.Local);
|
||||
else
|
||||
return dateTime.DateTime;
|
||||
}
|
||||
|
||||
internal static object To(object value, Type destinationType)
|
||||
{
|
||||
return To(value, destinationType, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
internal static object To(object value, Type destinationType, CultureInfo culture)
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
destinationType = UtilMethods.GetUnderType(destinationType);
|
||||
var sourceType = value.GetType();
|
||||
|
||||
var destinationConverter = TypeDescriptor.GetConverter(destinationType);
|
||||
if (destinationConverter != null && destinationConverter.CanConvertFrom(value.GetType()))
|
||||
return destinationConverter.ConvertFrom(null, culture, value);
|
||||
|
||||
var sourceConverter = TypeDescriptor.GetConverter(sourceType);
|
||||
if (sourceConverter != null && sourceConverter.CanConvertTo(destinationType))
|
||||
return sourceConverter.ConvertTo(null, culture, value, destinationType);
|
||||
|
||||
if (destinationType.IsEnum && value is int)
|
||||
return Enum.ToObject(destinationType, (int)value);
|
||||
|
||||
if (!destinationType.IsInstanceOfType(value))
|
||||
return Convert.ChangeType(value, destinationType, culture);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
public static bool IsAnyAsyncMethod(StackFrame[] methods)
|
||||
{
|
||||
bool isAsync = false;
|
||||
foreach (var item in methods)
|
||||
{
|
||||
if (UtilMethods.IsAsyncMethod(item.GetMethod()))
|
||||
{
|
||||
isAsync = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return isAsync;
|
||||
}
|
||||
|
||||
public static bool IsAsyncMethod(MethodBase method)
|
||||
{
|
||||
if (method == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (method.DeclaringType != null)
|
||||
{
|
||||
if (method.DeclaringType.GetInterfaces().Contains(typeof(IAsyncStateMachine)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
var name = method.Name;
|
||||
if (name.Contains("OutputAsyncCausalityEvents"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (name.Contains("OutputWaitEtwEvents"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (name.Contains("ExecuteAsync"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
Type attType = typeof(AsyncStateMachineAttribute);
|
||||
var attrib = (AsyncStateMachineAttribute)method.GetCustomAttribute(attType);
|
||||
return (attrib != null);
|
||||
}
|
||||
|
||||
public static StackTraceInfo GetStackTrace()
|
||||
{
|
||||
|
||||
StackTrace st = new StackTrace(true);
|
||||
StackTraceInfo info = new StackTraceInfo();
|
||||
info.MyStackTraceList = new List<StackTraceInfoItem>();
|
||||
info.SugarStackTraceList = new List<StackTraceInfoItem>();
|
||||
for (int i = 0; i < st.FrameCount; i++)
|
||||
{
|
||||
var frame = st.GetFrame(i);
|
||||
if (frame.GetMethod().Module.Name.ToLower() != "sqlsugar.dll" && frame.GetMethod().Name.First() != '<')
|
||||
{
|
||||
info.MyStackTraceList.Add(new StackTraceInfoItem()
|
||||
{
|
||||
FileName = frame.GetFileName(),
|
||||
MethodName = frame.GetMethod().Name,
|
||||
Line = frame.GetFileLineNumber()
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
info.SugarStackTraceList.Add(new StackTraceInfoItem()
|
||||
{
|
||||
FileName = frame.GetFileName(),
|
||||
MethodName = frame.GetMethod().Name,
|
||||
Line = frame.GetFileLineNumber()
|
||||
});
|
||||
}
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
internal static T To<T>(object value)
|
||||
{
|
||||
return (T)To(value, typeof(T));
|
||||
}
|
||||
internal static Type GetUnderType(Type oldType)
|
||||
{
|
||||
Type type = Nullable.GetUnderlyingType(oldType);
|
||||
return type == null ? oldType : type;
|
||||
}
|
||||
public static string ReplaceSqlParameter(string itemSql, SugarParameter itemParameter, string newName)
|
||||
{
|
||||
itemSql = Regex.Replace(itemSql, string.Format(@"{0} ", "\\" + itemParameter.ParameterName), newName + " ", RegexOptions.IgnoreCase);
|
||||
itemSql = Regex.Replace(itemSql, string.Format(@"{0}\)", "\\" + itemParameter.ParameterName), newName + ")", RegexOptions.IgnoreCase);
|
||||
itemSql = Regex.Replace(itemSql, string.Format(@"{0}\,", "\\" + itemParameter.ParameterName), newName + ",", RegexOptions.IgnoreCase);
|
||||
itemSql = Regex.Replace(itemSql, string.Format(@"{0}$", "\\" + itemParameter.ParameterName), newName, RegexOptions.IgnoreCase);
|
||||
itemSql = Regex.Replace(itemSql, string.Format(@"\+{0}\+", "\\" + itemParameter.ParameterName), "+" + newName + "+", RegexOptions.IgnoreCase);
|
||||
itemSql = Regex.Replace(itemSql, string.Format(@"\+{0} ", "\\" + itemParameter.ParameterName), "+" + newName + " ", RegexOptions.IgnoreCase);
|
||||
itemSql = Regex.Replace(itemSql, string.Format(@" {0}\+", "\\" + itemParameter.ParameterName), " " + newName + "+", RegexOptions.IgnoreCase);
|
||||
itemSql = Regex.Replace(itemSql, string.Format(@"\|\|{0}\|\|", "\\" + itemParameter.ParameterName), "||" + newName + "||", RegexOptions.IgnoreCase);
|
||||
itemSql = Regex.Replace(itemSql, string.Format(@"\={0}\+", "\\" + itemParameter.ParameterName), "=" + newName + "+", RegexOptions.IgnoreCase);
|
||||
itemSql = Regex.Replace(itemSql, string.Format(@"{0}\|\|", "\\" + itemParameter.ParameterName), newName + "||", RegexOptions.IgnoreCase);
|
||||
return itemSql;
|
||||
}
|
||||
internal static Type GetRootBaseType(Type entityType)
|
||||
{
|
||||
var baseType = entityType.BaseType;
|
||||
while (baseType != null && baseType.BaseType != UtilConstants.ObjType)
|
||||
{
|
||||
baseType = baseType.BaseType;
|
||||
}
|
||||
return baseType;
|
||||
}
|
||||
|
||||
|
||||
internal static Type GetUnderType(PropertyInfo propertyInfo, ref bool isNullable)
|
||||
{
|
||||
Type unType = Nullable.GetUnderlyingType(propertyInfo.PropertyType);
|
||||
isNullable = unType != null;
|
||||
unType = unType ?? propertyInfo.PropertyType;
|
||||
return unType;
|
||||
}
|
||||
|
||||
internal static Type GetUnderType(PropertyInfo propertyInfo)
|
||||
{
|
||||
Type unType = Nullable.GetUnderlyingType(propertyInfo.PropertyType);
|
||||
unType = unType ?? propertyInfo.PropertyType;
|
||||
return unType;
|
||||
}
|
||||
|
||||
internal static bool IsNullable(PropertyInfo propertyInfo)
|
||||
{
|
||||
Type unType = Nullable.GetUnderlyingType(propertyInfo.PropertyType);
|
||||
return unType != null;
|
||||
}
|
||||
|
||||
internal static bool IsNullable(Type type)
|
||||
{
|
||||
Type unType = Nullable.GetUnderlyingType(type);
|
||||
return unType != null;
|
||||
}
|
||||
//internal static T IsNullReturnNew<T>(T returnObj) where T : new()
|
||||
//{
|
||||
// if (returnObj.IsNullOrEmpty())
|
||||
// {
|
||||
// returnObj = new T();
|
||||
// }
|
||||
// return returnObj;
|
||||
//}
|
||||
public static object ChangeType2(object value, Type type)
|
||||
{
|
||||
if (value == null && type.IsGenericType) return Activator.CreateInstance(type);
|
||||
if (value == null) return null;
|
||||
if (type == value.GetType()) return value;
|
||||
if (type.IsEnum)
|
||||
{
|
||||
if (value is string)
|
||||
return Enum.Parse(type, value as string);
|
||||
else
|
||||
return Enum.ToObject(type, value);
|
||||
}
|
||||
if (!type.IsInterface && type.IsGenericType)
|
||||
{
|
||||
Type innerType = type.GetGenericArguments()[0];
|
||||
object innerValue = ChangeType(value, innerType);
|
||||
return Activator.CreateInstance(type, new object[] { innerValue });
|
||||
}
|
||||
if (value is string && type == typeof(Guid)) return new Guid(value as string);
|
||||
if (value is string && type == typeof(Version)) return new Version(value as string);
|
||||
if (!(value is IConvertible)) return value;
|
||||
return Convert.ChangeType(value, type);
|
||||
}
|
||||
|
||||
internal static T ChangeType<T>(T obj, Type type)
|
||||
{
|
||||
return (T)Convert.ChangeType(obj, type);
|
||||
}
|
||||
|
||||
internal static T ChangeType<T>(T obj)
|
||||
{
|
||||
return (T)Convert.ChangeType(obj, typeof(T));
|
||||
}
|
||||
|
||||
internal static DateTimeOffset GetDateTimeOffsetByDateTime(DateTime date)
|
||||
{
|
||||
date = DateTime.SpecifyKind(date, DateTimeKind.Utc);
|
||||
DateTimeOffset utcTime2 = date;
|
||||
return utcTime2;
|
||||
}
|
||||
|
||||
//internal static void RepairReplicationParameters(ref string appendSql, SugarParameter[] parameters, int addIndex, string append = null)
|
||||
//{
|
||||
// if (appendSql.HasValue() && parameters.HasValue())
|
||||
// {
|
||||
// foreach (var parameter in parameters.OrderByDescending(it => it.ParameterName.Length))
|
||||
// {
|
||||
// //Compatible with.NET CORE parameters case
|
||||
// var name = parameter.ParameterName;
|
||||
// string newName = name + append + addIndex;
|
||||
// appendSql = ReplaceSqlParameter(appendSql, parameter, newName);
|
||||
// parameter.ParameterName = newName;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
internal static string GetPackTable(string sql, string shortName)
|
||||
{
|
||||
return string.Format(" ({0}) {1} ", sql, shortName);
|
||||
}
|
||||
|
||||
public static Func<string, object> GetTypeConvert(object value)
|
||||
{
|
||||
if (value is int || value is uint || value is int? || value is uint?)
|
||||
{
|
||||
return x => Convert.ToInt32(x);
|
||||
}
|
||||
else if (value is short || value is ushort || value is short? || value is ushort?)
|
||||
{
|
||||
return x => Convert.ToInt16(x);
|
||||
}
|
||||
else if (value is long || value is long? || value is ulong? || value is long?)
|
||||
{
|
||||
return x => Convert.ToInt64(x);
|
||||
}
|
||||
else if (value is DateTime|| value is DateTime?)
|
||||
{
|
||||
return x => Convert.ToDateTime(x);
|
||||
}
|
||||
else if (value is bool||value is bool?)
|
||||
{
|
||||
return x => Convert.ToBoolean(x);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
internal static string GetTypeName(object value)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return value.GetType().Name;
|
||||
}
|
||||
}
|
||||
|
||||
internal static string GetParenthesesValue(string dbTypeName)
|
||||
{
|
||||
if (Regex.IsMatch(dbTypeName, @"\(.+\)"))
|
||||
{
|
||||
dbTypeName = Regex.Replace(dbTypeName, @"\(.+\)", "");
|
||||
}
|
||||
dbTypeName = dbTypeName.Trim();
|
||||
return dbTypeName;
|
||||
}
|
||||
|
||||
internal static T GetOldValue<T>(T value, Action action)
|
||||
{
|
||||
action();
|
||||
return value;
|
||||
}
|
||||
|
||||
internal static object DefaultForType(Type targetType)
|
||||
{
|
||||
return targetType.IsValueType ? Activator.CreateInstance(targetType) : null;
|
||||
}
|
||||
|
||||
internal static Int64 GetLong(byte[] bytes)
|
||||
{
|
||||
return Convert.ToInt64(string.Join("", bytes).PadRight(20, '0'));
|
||||
}
|
||||
public static object GetPropertyValue<T>(T t, string PropertyName)
|
||||
{
|
||||
return t.GetType().GetProperty(PropertyName).GetValue(t, null);
|
||||
}
|
||||
internal static string GetMD5(string myString)
|
||||
{
|
||||
MD5 md5 = new MD5CryptoServiceProvider();
|
||||
byte[] fromData = System.Text.Encoding.Unicode.GetBytes(myString);
|
||||
byte[] targetData = md5.ComputeHash(fromData);
|
||||
string byte2String = null;
|
||||
|
||||
for (int i = 0; i < targetData.Length; i++)
|
||||
{
|
||||
byte2String += targetData[i].ToString("x");
|
||||
}
|
||||
|
||||
return byte2String;
|
||||
}
|
||||
|
||||
//public static string EncodeBase64(string code)
|
||||
//{
|
||||
// if (code.IsNullOrEmpty()) return code;
|
||||
// string encode = "";
|
||||
// byte[] bytes = Encoding.GetEncoding("utf-8").GetBytes(code);
|
||||
// try
|
||||
// {
|
||||
// encode = Convert.ToBase64String(bytes);
|
||||
// }
|
||||
// catch
|
||||
// {
|
||||
// encode = code;
|
||||
// }
|
||||
// return encode;
|
||||
//}
|
||||
public static string ConvertNumbersToString(string value)
|
||||
{
|
||||
string[] splitInt = value.Split(new char[] { '9' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
var splitChars = splitInt.Select(s => Convert.ToChar(
|
||||
Convert.ToInt32(s, 8)
|
||||
).ToString());
|
||||
|
||||
return string.Join("", splitChars);
|
||||
}
|
||||
public static string ConvertStringToNumbers(string value)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
foreach (char c in value)
|
||||
{
|
||||
int cAscil = (int)c;
|
||||
sb.Append(Convert.ToString(c, 8) + "9");
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
//public static string DecodeBase64(string code)
|
||||
//{
|
||||
// try
|
||||
// {
|
||||
// if (code.IsNullOrEmpty()) return code;
|
||||
// string decode = "";
|
||||
// byte[] bytes = Convert.FromBase64String(code);
|
||||
// try
|
||||
// {
|
||||
// decode = Encoding.GetEncoding("utf-8").GetString(bytes);
|
||||
// }
|
||||
// catch
|
||||
// {
|
||||
// decode = code;
|
||||
// }
|
||||
// return decode;
|
||||
// }
|
||||
// catch
|
||||
// {
|
||||
// return code;
|
||||
// }
|
||||
//}
|
||||
|
||||
public static void DataInoveByExpresson<Type>(Type[] datas, MethodCallExpression callExpresion)
|
||||
{
|
||||
var methodInfo = callExpresion.Method;
|
||||
foreach (var item in datas)
|
||||
{
|
||||
if (callExpresion.Arguments.Count == 0)
|
||||
{
|
||||
methodInfo.Invoke(item, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<object> methodParameters = new List<object>();
|
||||
foreach (var callItem in callExpresion.Arguments)
|
||||
{
|
||||
var parameter = callItem.GetType().GetProperties().FirstOrDefault(it => it.Name == "Value");
|
||||
if (parameter == null)
|
||||
{
|
||||
var value = LambdaExpression.Lambda(callItem).Compile().DynamicInvoke();
|
||||
methodParameters.Add(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
var value = parameter.GetValue(callItem, null);
|
||||
methodParameters.Add(value);
|
||||
}
|
||||
}
|
||||
methodInfo.Invoke(item, methodParameters.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Dictionary<string, T> EnumToDictionary<T>()
|
||||
{
|
||||
Dictionary<string, T> dic = new Dictionary<string, T>();
|
||||
if (!typeof(T).IsEnum)
|
||||
{
|
||||
return dic;
|
||||
}
|
||||
string desc = string.Empty;
|
||||
foreach (var item in Enum.GetValues(typeof(T)))
|
||||
{
|
||||
var key = item.ToString().ToLower();
|
||||
if (!dic.ContainsKey(key))
|
||||
dic.Add(key, (T)item);
|
||||
}
|
||||
return dic;
|
||||
}
|
||||
//public static object ConvertDataByTypeName(string ctypename,string value)
|
||||
//{
|
||||
// var item = new ConditionalModel() {
|
||||
// CSharpTypeName = ctypename,
|
||||
// FieldValue = value
|
||||
// };
|
||||
// if (item.CSharpTypeName.EqualCase(UtilConstants.DecType.Name))
|
||||
// {
|
||||
// return Convert.ToDecimal(item.FieldValue);
|
||||
// }
|
||||
// else if (item.CSharpTypeName.EqualCase(UtilConstants.DobType.Name))
|
||||
// {
|
||||
// return Convert.ToDouble(item.FieldValue);
|
||||
// }
|
||||
// else if (item.CSharpTypeName.EqualCase(UtilConstants.DateType.Name))
|
||||
// {
|
||||
// return Convert.ToDateTime(item.FieldValue);
|
||||
// }
|
||||
// else if (item.CSharpTypeName.EqualCase(UtilConstants.IntType.Name))
|
||||
// {
|
||||
// return Convert.ToInt32(item.FieldValue);
|
||||
// }
|
||||
// else if (item.CSharpTypeName.EqualCase(UtilConstants.LongType.Name))
|
||||
// {
|
||||
// return Convert.ToInt64(item.FieldValue);
|
||||
// }
|
||||
// else if (item.CSharpTypeName.EqualCase(UtilConstants.ShortType.Name))
|
||||
// {
|
||||
// return Convert.ToInt16(item.FieldValue);
|
||||
// }
|
||||
// else if (item.CSharpTypeName.EqualCase(UtilConstants.DateTimeOffsetType.Name))
|
||||
// {
|
||||
// return UtilMethods.GetDateTimeOffsetByDateTime(Convert.ToDateTime(item.FieldValue));
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return item.FieldValue;
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
||||
172
Src/Asp.NetCore2/SqlSugar.DuckDBCore/Tools/ValidateExtensions.cs
Normal file
172
Src/Asp.NetCore2/SqlSugar.DuckDBCore/Tools/ValidateExtensions.cs
Normal file
@@ -0,0 +1,172 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
namespace SqlSugar.DuckDB
|
||||
{
|
||||
internal static class ValidateExtensions
|
||||
{
|
||||
public static bool IsInRange(this int thisValue, int begin, int end)
|
||||
{
|
||||
return thisValue >= begin && thisValue <= end;
|
||||
}
|
||||
|
||||
public static bool IsInRange(this DateTime thisValue, DateTime begin, DateTime end)
|
||||
{
|
||||
return thisValue >= begin && thisValue <= end;
|
||||
}
|
||||
|
||||
public static bool IsIn<T>(this T thisValue, params T[] values)
|
||||
{
|
||||
return values.Contains(thisValue);
|
||||
}
|
||||
|
||||
public static bool IsContainsIn(this string thisValue, params string[] inValues)
|
||||
{
|
||||
return inValues.Any(it => thisValue.Contains(it));
|
||||
}
|
||||
|
||||
public static bool IsNullOrEmpty(this object thisValue)
|
||||
{
|
||||
if (thisValue == null || thisValue == DBNull.Value) return true;
|
||||
return thisValue.ToString() == "";
|
||||
}
|
||||
|
||||
public static bool IsNullOrEmpty(this Guid? thisValue)
|
||||
{
|
||||
if (thisValue == null) return true;
|
||||
return thisValue == Guid.Empty;
|
||||
}
|
||||
|
||||
public static bool IsNullOrEmpty(this Guid thisValue)
|
||||
{
|
||||
if (thisValue == null) return true;
|
||||
return thisValue == Guid.Empty;
|
||||
}
|
||||
|
||||
public static bool IsNullOrEmpty(this IEnumerable<object> thisValue)
|
||||
{
|
||||
if (thisValue == null || thisValue.Count() == 0) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool HasValue(this object thisValue)
|
||||
{
|
||||
if (thisValue == null || thisValue == DBNull.Value) return false;
|
||||
return thisValue.ToString() != "";
|
||||
}
|
||||
|
||||
public static bool HasValue(this IEnumerable<object> thisValue)
|
||||
{
|
||||
if (thisValue == null || thisValue.Count() == 0) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool IsValuable(this IEnumerable<KeyValuePair<string,string>> thisValue)
|
||||
{
|
||||
if (thisValue == null || thisValue.Count() == 0) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool IsZero(this object thisValue)
|
||||
{
|
||||
return (thisValue == null || thisValue.ToString() == "0");
|
||||
}
|
||||
|
||||
public static bool IsInt(this object thisValue)
|
||||
{
|
||||
if (thisValue == null) return false;
|
||||
return Regex.IsMatch(thisValue.ToString(), @"^\d+$");
|
||||
}
|
||||
|
||||
/// <returns></returns>
|
||||
public static bool IsNoInt(this object thisValue)
|
||||
{
|
||||
if (thisValue == null) return true;
|
||||
return !Regex.IsMatch(thisValue.ToString(), @"^\d+$");
|
||||
}
|
||||
|
||||
public static bool IsMoney(this object thisValue)
|
||||
{
|
||||
if (thisValue == null) return false;
|
||||
double outValue = 0;
|
||||
return double.TryParse(thisValue.ToString(), out outValue);
|
||||
}
|
||||
public static bool IsGuid(this object thisValue)
|
||||
{
|
||||
if (thisValue == null) return false;
|
||||
Guid outValue = Guid.Empty;
|
||||
return Guid.TryParse(thisValue.ToString(), out outValue);
|
||||
}
|
||||
|
||||
public static bool IsDate(this object thisValue)
|
||||
{
|
||||
if (thisValue == null) return false;
|
||||
DateTime outValue = DateTime.MinValue;
|
||||
return DateTime.TryParse(thisValue.ToString(), out outValue);
|
||||
}
|
||||
|
||||
public static bool IsEamil(this object thisValue)
|
||||
{
|
||||
if (thisValue == null) return false;
|
||||
return Regex.IsMatch(thisValue.ToString(), @"^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$");
|
||||
}
|
||||
|
||||
public static bool IsMobile(this object thisValue)
|
||||
{
|
||||
if (thisValue == null) return false;
|
||||
return Regex.IsMatch(thisValue.ToString(), @"^\d{11}$");
|
||||
}
|
||||
|
||||
public static bool IsTelephone(this object thisValue)
|
||||
{
|
||||
if (thisValue == null) return false;
|
||||
return System.Text.RegularExpressions.Regex.IsMatch(thisValue.ToString(), @"^(\(\d{3,4}\)|\d{3,4}-|\s)?\d{8}$");
|
||||
|
||||
}
|
||||
|
||||
public static bool IsIDcard(this object thisValue)
|
||||
{
|
||||
if (thisValue == null) return false;
|
||||
return System.Text.RegularExpressions.Regex.IsMatch(thisValue.ToString(), @"^(\d{15}$|^\d{18}$|^\d{17}(\d|X|x))$");
|
||||
}
|
||||
|
||||
public static bool IsFax(this object thisValue)
|
||||
{
|
||||
if (thisValue == null) return false;
|
||||
return System.Text.RegularExpressions.Regex.IsMatch(thisValue.ToString(), @"^[+]{0,1}(\d){1,3}[ ]?([-]?((\d)|[ ]){1,12})+$");
|
||||
}
|
||||
|
||||
public static bool IsMatch(this object thisValue, string pattern)
|
||||
{
|
||||
if (thisValue == null) return false;
|
||||
Regex reg = new Regex(pattern);
|
||||
return reg.IsMatch(thisValue.ToString());
|
||||
}
|
||||
public static bool IsAnonymousType(this Type type)
|
||||
{
|
||||
string typeName = type.Name;
|
||||
return typeName.Contains("<>") && typeName.Contains("__") && typeName.Contains("AnonymousType");
|
||||
}
|
||||
public static bool IsCollectionsList(this string thisValue)
|
||||
{
|
||||
return (thisValue + "").StartsWith("System.Collections.Generic.List")|| (thisValue + "").StartsWith("System.Collections.Generic.IEnumerable");
|
||||
}
|
||||
public static bool IsStringArray(this string thisValue)
|
||||
{
|
||||
return (thisValue + "").IsMatch(@"System\.[a-z,A-Z,0-9]+?\[\]");
|
||||
}
|
||||
public static bool IsEnumerable(this string thisValue)
|
||||
{
|
||||
return (thisValue + "").StartsWith("System.Linq.Enumerable");
|
||||
}
|
||||
|
||||
public static Type StringType = typeof (string);
|
||||
|
||||
public static bool IsClass(this Type thisValue)
|
||||
{
|
||||
return thisValue != StringType && thisValue.IsEntity()&&thisValue!=UtilConstants.ByteArrayType;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -94,6 +94,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SqlSugar.GaussDBCore", "Sql
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GaussDBTest", "GaussTest\GaussDBTest.csproj", "{F17886C5-60CB-4B69-9B0A-7E07E073B385}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SqlSugar.DuckDBCore", "SqlSugar.DuckDBCore\SqlSugar.DuckDBCore.csproj", "{7AF1C5DF-AEA1-47E2-92CA-621330F68860}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DuckDBTest", "DuckDBTest\DuckDBTest.csproj", "{F8DBA187-9A40-4AE5-972F-230835FEAEE4}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -608,6 +612,30 @@ Global
|
||||
{F17886C5-60CB-4B69-9B0A-7E07E073B385}.Release|ARM32.Build.0 = Release|Any CPU
|
||||
{F17886C5-60CB-4B69-9B0A-7E07E073B385}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{F17886C5-60CB-4B69-9B0A-7E07E073B385}.Release|x86.Build.0 = Release|Any CPU
|
||||
{7AF1C5DF-AEA1-47E2-92CA-621330F68860}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7AF1C5DF-AEA1-47E2-92CA-621330F68860}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7AF1C5DF-AEA1-47E2-92CA-621330F68860}.Debug|ARM32.ActiveCfg = Debug|Any CPU
|
||||
{7AF1C5DF-AEA1-47E2-92CA-621330F68860}.Debug|ARM32.Build.0 = Debug|Any CPU
|
||||
{7AF1C5DF-AEA1-47E2-92CA-621330F68860}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{7AF1C5DF-AEA1-47E2-92CA-621330F68860}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{7AF1C5DF-AEA1-47E2-92CA-621330F68860}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7AF1C5DF-AEA1-47E2-92CA-621330F68860}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7AF1C5DF-AEA1-47E2-92CA-621330F68860}.Release|ARM32.ActiveCfg = Release|Any CPU
|
||||
{7AF1C5DF-AEA1-47E2-92CA-621330F68860}.Release|ARM32.Build.0 = Release|Any CPU
|
||||
{7AF1C5DF-AEA1-47E2-92CA-621330F68860}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{7AF1C5DF-AEA1-47E2-92CA-621330F68860}.Release|x86.Build.0 = Release|Any CPU
|
||||
{F8DBA187-9A40-4AE5-972F-230835FEAEE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F8DBA187-9A40-4AE5-972F-230835FEAEE4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F8DBA187-9A40-4AE5-972F-230835FEAEE4}.Debug|ARM32.ActiveCfg = Debug|Any CPU
|
||||
{F8DBA187-9A40-4AE5-972F-230835FEAEE4}.Debug|ARM32.Build.0 = Debug|Any CPU
|
||||
{F8DBA187-9A40-4AE5-972F-230835FEAEE4}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{F8DBA187-9A40-4AE5-972F-230835FEAEE4}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{F8DBA187-9A40-4AE5-972F-230835FEAEE4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F8DBA187-9A40-4AE5-972F-230835FEAEE4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F8DBA187-9A40-4AE5-972F-230835FEAEE4}.Release|ARM32.ActiveCfg = Release|Any CPU
|
||||
{F8DBA187-9A40-4AE5-972F-230835FEAEE4}.Release|ARM32.Build.0 = Release|Any CPU
|
||||
{F8DBA187-9A40-4AE5-972F-230835FEAEE4}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{F8DBA187-9A40-4AE5-972F-230835FEAEE4}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -626,6 +654,7 @@ Global
|
||||
{B3C4B993-C33E-48AF-955F-EB801774FBE8} = {88992AAF-146B-4253-9AD7-493E8F415B57}
|
||||
{F706204F-2FC4-5112-646F-28D498E56AF4} = {88992AAF-146B-4253-9AD7-493E8F415B57}
|
||||
{15CB3CFF-E99D-4A79-8F6F-D9175CC2F7CB} = {88992AAF-146B-4253-9AD7-493E8F415B57}
|
||||
{7AF1C5DF-AEA1-47E2-92CA-621330F68860} = {88992AAF-146B-4253-9AD7-493E8F415B57}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {230A85B9-54F1-41B1-B1DA-80086581B2B4}
|
||||
|
||||
Reference in New Issue
Block a user