Add DuckDB

This commit is contained in:
sunkaixuan
2025-04-20 12:40:39 +08:00
parent 8e7353e88a
commit 00afa949ac
43 changed files with 5539 additions and 0 deletions

View 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; }
}
}
}

View 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");
}
}
}

View 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; }
}
}
}

View 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相关属性...
}
}
}

View 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; }
}
}
}

View 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; }
}
}

View 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; }
}
}
}

View 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)
}
}
}

View 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: 返回雪花IDReturn 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; }
}
}
}

View 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; }
}
}
}

View 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>

View 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;
}

View 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; }
}
}
}

View 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; }
}
}
}

View 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; }
// 其他属性
}
}
}

View 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; }
}
}
}

View 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; }
}
}
}

View 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; }
}
}
}

View 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; }
}
}
}

View 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; }
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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" };
}
}
}
}

View File

@@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SqlSugar.DuckDB
{
public class DuckDBDbFirst : DbFirstProvider
{
}
}

View File

@@ -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
}
}

View 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);
}
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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>
{
}
}

View File

@@ -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;
}
}
}

View File

@@ -0,0 +1,7 @@
namespace SqlSugar.DuckDB
{
public class DuckDBDeleteBuilder : DeleteBuilder
{
}
}

View File

@@ -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";
}
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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") + "'";
}
}
}

View File

@@ -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
}
}

View File

@@ -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") + "'";
}
}
}

View 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());
}
}
}
}

View File

@@ -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>

View 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;
}
}
}
}

View 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);
}
}
}

View 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"
};
}
}

View 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;
}
}
}

View 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;
// }
//}
}
}

View 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;
}
}
}

View File

@@ -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}