Commit 483cd533 authored by 朱天博's avatar 朱天博

Merge branch 'master' of http://192.168.1.181/root/Ftt_Common

parents 6a6f312c be173998
......@@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tools", "Tools\Tools.csproj
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ftt.PatchPack", "Ftt.PatchPack\Ftt.PatchPack.csproj", "{42E384C1-CC13-494D-90E2-33C399E13F07}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test", "test\test.csproj", "{1447F8DF-E552-40DD-8F02-B55D75FBC77A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
......@@ -55,6 +57,18 @@ Global
{42E384C1-CC13-494D-90E2-33C399E13F07}.Release|x64.Build.0 = Release|Any CPU
{42E384C1-CC13-494D-90E2-33C399E13F07}.Release|x86.ActiveCfg = Release|Any CPU
{42E384C1-CC13-494D-90E2-33C399E13F07}.Release|x86.Build.0 = Release|Any CPU
{1447F8DF-E552-40DD-8F02-B55D75FBC77A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1447F8DF-E552-40DD-8F02-B55D75FBC77A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1447F8DF-E552-40DD-8F02-B55D75FBC77A}.Debug|x64.ActiveCfg = Debug|Any CPU
{1447F8DF-E552-40DD-8F02-B55D75FBC77A}.Debug|x64.Build.0 = Debug|Any CPU
{1447F8DF-E552-40DD-8F02-B55D75FBC77A}.Debug|x86.ActiveCfg = Debug|Any CPU
{1447F8DF-E552-40DD-8F02-B55D75FBC77A}.Debug|x86.Build.0 = Debug|Any CPU
{1447F8DF-E552-40DD-8F02-B55D75FBC77A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1447F8DF-E552-40DD-8F02-B55D75FBC77A}.Release|Any CPU.Build.0 = Release|Any CPU
{1447F8DF-E552-40DD-8F02-B55D75FBC77A}.Release|x64.ActiveCfg = Release|Any CPU
{1447F8DF-E552-40DD-8F02-B55D75FBC77A}.Release|x64.Build.0 = Release|Any CPU
{1447F8DF-E552-40DD-8F02-B55D75FBC77A}.Release|x86.ActiveCfg = Release|Any CPU
{1447F8DF-E552-40DD-8F02-B55D75FBC77A}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
......
......@@ -6,6 +6,48 @@ using System.Threading.Tasks;
namespace Tools.MyCommon
{
/*
* Info : 全局的基础信息
*/
/// <summary>
/// 模块信息:菜单渲染时使用
/// </summary>
public class ModuleInfo
{
/// <summary>
/// 窗体对象
/// </summary>
public Type ViewFormType { get; set; }
/// <summary>
/// 显示名称
/// </summary>
public string Text { get; set; }
/// <summary>
/// 提示内容
/// </summary>
public string ToolTipText { get; set; }
}
/// <summary>
/// 绑定信息
/// </summary>
public class BindInfo
{
/// <summary>
/// 绑定的数据源列名称
/// </summary>
public string ColumnName { get; set; }
/// <summary>
/// 绑定的控件属性名称
/// </summary>
public string PropertyName { get; set; }
}
/*
* Type:为部分模块提供相对规范的类型区分
*/
/// <summary>
/// 配置类型
/// </summary>
......@@ -46,22 +88,5 @@ namespace Tools.MyCommon
/// </summary>
public static string Doc => "Doc";
}
/// <summary>
/// 模块信息
/// </summary>
public class ModuleInfo
{
/// <summary>
/// 窗体对象
/// </summary>
public Type FrmView { get; set; }
/// <summary>
/// 显示名称
/// </summary>
public string Text { get; set; }
/// <summary>
/// 提示内容
/// </summary>
public string ToolTipText { get; set; }
}
}
......@@ -23,6 +23,10 @@ namespace Tools.MyCommon
/// 全局数据集:应该在InitData()中进行初始化
/// </summary>
DataSet _ds { get; set; }
/// <summary>
/// 模块表集合:通用保存必须初始化该项
/// </summary>
List<TQuery> ModuleTableList { get; set; }
/// <summary>
/// 初始化数据库访问对象
......
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
......@@ -27,6 +28,10 @@ namespace Tools.MyCommon
/// 全局数据集
/// </summary>
public DataSet _ds { get; set; }
/// <summary>
/// 模块表集合-用于保存
/// </summary>
public List<TQuery> ModuleTableList { get; set; }
/// <summary>
/// 构造函数
......@@ -88,7 +93,11 @@ namespace Tools.MyCommon
/// <returns></returns>
public virtual bool SaveCheck()
{
//保存之前的检查,全部放到此方法处理
//结束编辑
this.BaseInfoEndEdit();
this.DataGridViewCommitEditCell(this);
this.DataSetEndEdit(this._ds);
return true;
}
/// <summary>
......@@ -97,8 +106,155 @@ namespace Tools.MyCommon
/// <returns></returns>
public virtual bool Save()
{
//保存的逻辑放到此方法内实现
//保存检查
if (this._ds == null || !this.SaveCheck())
return false;
//未修改提示
if (!this._ds.HasChanges())
{
Utils.Tip("数据未修改!");
return true;
}
//保存数据
if (this._db.SaveData(this._ds.GetChanges(), this.ModuleTableList))
{
Utils.Tip("保存成功!");
}
return true;
}
#region 结束编辑
/// <summary>
/// 基本信息-结束编辑
/// </summary>
private void BaseInfoEndEdit()
{
BindingManagerBase bm;
foreach (DictionaryEntry item in this.BindingContext)
{
bm = (item.Value as WeakReference).Target as BindingManagerBase;
if (bm != null)
{
bm.EndCurrentEdit();
}
}
}
/// <summary>
/// 数据表格-提交编辑单元格
/// </summary>
/// <param name="root"></param>
private void DataGridViewCommitEditCell(Control root)
{
foreach (Control c in root.Controls)
{
if (c is DataGridView dgv)
{
dgv.CommitEdit(DataGridViewDataErrorContexts.Display);
continue;
}
//递归子控件
if (c.Controls.Count > 0)
{
this.DataGridViewCommitEditCell(c);
}
}
}
/// <summary>
/// 数据集-结束编辑
/// </summary>
/// <param name="ds"></param>
private void DataSetEndEdit(DataSet ds)
{
if (ds == null)
return;
foreach (DataTable dt in ds.Tables)
{
foreach (DataRow r in dt.Rows)
{
if (r.RowState != DataRowState.Deleted
&& r.RowState != DataRowState.Detached)
{
r.EndEdit();
}
}
}
}
#endregion
#region 数据绑定
/// <summary>
/// 绑定基础信息
/// </summary>
/// <param name="parent"></param>
/// <param name="drv"></param>
public void BindBaseInfo(Control parent, DataRowView drv)
{
foreach (Control c in parent?.Controls)
{
if (c is TextBox)
{
this.Binding(c as TextBox, drv);
}
else if (c is CheckBox)
{
this.Binding(c as CheckBox, drv);
}
}
}
/// <summary>
/// 设置控件绑定信息
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="c"></param>
/// <param name="drv"></param>
private void Binding<T>(T c, DataRowView drv) where T : Control
{
//获取绑定信息
var bind = this.GetBindingInfo(c);
//数据源是否包含该列
var field = bind.ColumnName;
if (!drv.Row.Table.Columns.Contains(field))
return;
//布尔特殊处理
if (drv[field] == DBNull.Value && drv.Row.Table.Columns[field].DataType.Name.Equals("Boolean"))
drv[field] = false;
//设置绑定
var property = bind.PropertyName;
c.DataBindings.Clear();
c.DataBindings.Add(property, drv, field);
}
/// <summary>
/// 获取绑定属性名称
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="c"></param>
/// <returns></returns>
private BindInfo GetBindingInfo<T>(T c) where T : Control
{
var property = "";
var column = "";
if (c is TextBox)
{
property = "Text";
column = c.Name.Substring(2);
}
else if (c is CheckBox)
{
property = "Checked";
column = c.Name.Substring(2);
}
return new BindInfo() { ColumnName = column, PropertyName = property };
}
#endregion
}
}
......@@ -4,6 +4,7 @@ using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
//
......@@ -83,6 +84,76 @@ namespace Tools.MyUtils
Process.Start("notepad.exe", fileName);
}
#endregion
#region 加密解密
private static string KEY_ENCRYPT = "c_dc";
/// <summary>
/// 解密字符串
/// </summary>
/// <param name="pDecryptStr"></param>
/// <returns></returns>
public static string DecryptString(string pDecryptStr)
{
DESCryptoServiceProvider desc = new DESCryptoServiceProvider();
//产生key
PasswordDeriveBytes db = new PasswordDeriveBytes(KEY_ENCRYPT, null);
byte[] key = db.GetBytes(8);
//存储解密后的数据
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, desc.CreateDecryptor(key, key), CryptoStreamMode.Write);
//取到加密后的数据的字节流,如果是保存到文件
try
{
byte[] databytes = Convert.FromBase64String(pDecryptStr);
//解密数据
cs.Write(databytes, 0, databytes.Length);
cs.FlushFinalBlock();
byte[] res = ms.ToArray();
//返回解密后的数据,这里返回的数据应该和参数pwd的值相同。
return System.Text.Encoding.UTF8.GetString(res);
}
catch
{
Utils.Tip($"字符串{pDecryptStr}解密不成功。");
return null;
}
}
/// <summary>
/// 加密字符串
/// </summary>
/// <param name="pEncryptedStr"></param>
/// <returns></returns>
public static string EncryptString(string pEncryptedStr)
{
//des进行加密
DESCryptoServiceProvider desc = new DESCryptoServiceProvider();
//产生key
PasswordDeriveBytes db = new PasswordDeriveBytes(KEY_ENCRYPT, null);
byte[] key = db.GetBytes(8);
//存储加密后的数据
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, desc.CreateEncryptor(key, key), CryptoStreamMode.Write);
//取到密码的字节流
try
{
byte[] data = Encoding.UTF8.GetBytes(pEncryptedStr);
//进行加密
cs.Write(data, 0, data.Length);
cs.FlushFinalBlock();
//取加密后的数据
byte[] res = ms.ToArray();
return Convert.ToBase64String(res);
}
catch
{
Utils.Tip($"字符串{pEncryptedStr}加密不成功。");
return null;
}
}
#endregion
#region winform:提示;帮助窗口;异步UI支持
......@@ -213,10 +284,8 @@ namespace Tools.MyUtils
{
if (c.AllowDBNull || c.AutoIncrement)
continue;
//非空列处理:主键列根据列类型生成;非主键列统一用0初始化
// 非空主键可以自动赋值,其他列用0 未考虑数据类型会直接报错
result[c.ColumnName] = dt.PrimaryKey.Contains(c) ? GetDefaultPrimaryKey(c) : GetDefaultColumnValue(c);
//非空列初始化,主要是主键
result[c.ColumnName] = GetDefaultColumnValue(c);
result.EndEdit();
}
//当有筛选条件时,默认赋值筛选字段
......@@ -240,13 +309,13 @@ namespace Tools.MyUtils
return result;
}
/// <summary>
/// 【私有】获取默认主键值(防止创建新行时,主键为空报错)
/// 【私有】获取列默认值(防止创建新行时,非空列报错)
/// </summary>
/// <param name="c"></param>
/// <returns></returns>
private static string GetDefaultPrimaryKey(DataColumn c)
private static string GetDefaultColumnValue(DataColumn c)
{
var result = "";
var result = "0";
var typeName = c.DataType.Name.ToLower();
if (typeName.Equals("int32") || typeName.Equals("int64"))
......@@ -259,6 +328,10 @@ namespace Tools.MyUtils
{
result = Guid.NewGuid().ToString();
}
else if (typeName.Equals("datetime"))
{
result = Utils.Now();
}
else
{
result = $"{c.ColumnName}_{c.Table.Rows.Count}";
......@@ -267,42 +340,31 @@ namespace Tools.MyUtils
return result;
}
private static object GetDefaultColumnValue(DataColumn c)
{
object result = "0";
var typeName = c.DataType.Name.ToLower();
if (typeName.Equals("int32") || typeName.Equals("int64"))
/// <summary>
/// 复制两行(针对相同结构,不同结构只复制相同列)
/// </summary>
/// <param name="drFrom">源行</param>
/// <param name="drTarget">目标行</param>
/// <param name="ExceptList">除外的列(即其中包含的列不复制到目标行)</param>
public static void CopyRow(DataRow drFrom, DataRow drTarget, List<string> ExceptList = null)
{
var obj = c.Table.Compute($"Max({c.ColumnName})", "1=1");
int.TryParse(obj?.ToString(), out int max);
result = (max + 1).ToString();
}
else if (typeName.Equals("guid"))
if (drFrom == null || drTarget == null)
return;
//
foreach (DataColumn c in drFrom.Table.Columns)
{
result = Guid.NewGuid().ToString();
}
else if (typeName.Equals("datetime"))
string ColName = c.ColumnName;
//ID和指定列不复制
if (ColName.ToLower().Equals("id") || ExceptList?.IndexOf(ColName) >= 0)
continue;
if (drTarget.Table.Columns.Contains(ColName))
{
result = DateTime.Now;
drTarget[ColName] = drFrom[ColName];
}
else
{
result = $"{c.ColumnName}_{c.Table.Rows.Count}";
drTarget.EndEdit();
}
return result;
}
#endregion
#region (扩展)整型范围
......@@ -391,10 +453,25 @@ namespace Tools.MyUtils
#endregion
#region 生成SQL
#region 生成创建表的语句
/// <summary>
/// 生成SQL头部
/// </summary>
/// <param name="tableName"></param>
/// <returns></returns>
public static string GenSqlHead(string tableName)
{
return $"IF NOT EXISTS(SELECT 1 FROM sys.tables WHERE name = '{tableName}')\r\nBEGIN\r\nCREATE TABLE {tableName}\r\n(";
}
/// <summary>
/// 生成SQL主体
/// </summary>
/// <param name="dt"></param>
/// <param name="tableName"></param>
/// <param name="tableDescription"></param>
/// <param name="descriptionList">Out:列描述信息通过存储过程创建,此处生成语句并以输出参数形式返回</param>
/// <returns></returns>
public static string GenSqlBody(DataTable dt, string tableName, string tableDescription, out List<string> descriptionList)
{
//描述信息
......@@ -429,11 +506,75 @@ namespace Tools.MyUtils
return string.Join(",\r\n", columnInfoList);
}
/// <summary>
/// 生成SQL尾部
/// </summary>
/// <returns></returns>
public static string GenSqlTail()
{
return $");\r\nEND;";
}
#endregion
#region 生成Insert语句
/// <summary>
/// 生成表格Insert语句
/// </summary>
/// <param name="rows"></param>
/// <returns></returns>
public static string GenInsertSQL(params DataRow[] rows)
{
if (rows == null || rows.Length == 0)
return "";
//
var dt = rows[0].Table;
var colist = Utils.GetTableColumns(dt);
var values = rows.Select(r => Utils.GenValues(r, colist));
var result = $"INSERT INTO {dt.TableName}\r\n\t{Utils.GenColumns(colist)}\r\nVALUES\r\n\t{string.Join(",\r\n\t", values)}";
return result;
}
/// <summary>
/// 生成列集合
/// </summary>
/// <param name="colist"></param>
/// <returns></returns>
private static string GenColumns(List<string> colist)
{
return $"([{string.Join("], [", colist)}])";
}
/// <summary>
/// 生成值集合(此处将所有值转为字符串处理,后续可细化按类型转换)
/// </summary>
/// <param name="dr"></param>
/// <param name="colist"></param>
/// <returns></returns>
private static string GenValues(DataRow dr, List<string> colist)
{
var valist = colist.Select(col => col.ToLower().Equals("modelid") ? "@ModelID" : $"'{dr[col].ToString()}'");
return $"({string.Join(", ", valist)})";
}
/// <summary>
/// 获取有效列(只取非自增列)
/// </summary>
/// <param name="dt"></param>
/// <returns></returns>
private static List<string> GetTableColumns(DataTable dt)
{
var result = new List<string>();
dt.Columns.Cast<DataColumn>().ToList()
.ForEach(c => {
if (!c.AutoIncrement)
{
result.Add(c.ColumnName);
}
});
return result;
}
#endregion
#endregion
#region 汉字拼音缩写
......@@ -468,29 +609,29 @@ namespace Tools.MyUtils
//转为汉字域码:高字节左移8位,加上低位字节
int n = (gbytes[0] << 8) + gbytes[1];
//根据汉字域码获取拼音首字母
if (n.Between(0xB0A1, 0xB0C4)) return 'a';
if (n.Between(0XB0C5, 0XB2C0)) return 'b';
if (n.Between(0xB2C1, 0xB4ED)) return 'c';
if (n.Between(0xB4EE, 0xB6E9)) return 'd';
if (n.Between(0xB6EA, 0xB7A1)) return 'e';
if (n.Between(0xB7A2, 0xB8c0)) return 'f';
if (n.Between(0xB8C1, 0xB9FD)) return 'g';
if (n.Between(0xB9FE, 0xBBF6)) return 'h';
if (n.Between(0xBBF7, 0xBFA5)) return 'j';
if (n.Between(0xBFA6, 0xC0AB)) return 'k';
if (n.Between(0xC0AC, 0xC2E7)) return 'l';
if (n.Between(0xC2E8, 0xC4C2)) return 'm';
if (n.Between(0xC4C3, 0xC5B5)) return 'n';
if (n.Between(0xC5B6, 0xC5BD)) return 'o';
if (n.Between(0xC5BE, 0xC6D9)) return 'p';
if (n.Between(0xC6DA, 0xC8BA)) return 'q';
if (n.Between(0xC8BB, 0xC8F5)) return 'r';
if (n.Between(0xC8F6, 0xCBF9)) return 's';
if (n.Between(0xCBFA, 0xCDD9)) return 't';
if (n.Between(0xCDDA, 0xCEF3)) return 'w';
if (n.Between(0xCEF4, 0xD188)) return 'x';
if (n.Between(0xD1B9, 0xD4D0)) return 'y';
if (n.Between(0xD4D1, 0xD7F9)) return 'z';
if (n.Between(0xB0A1, 0xB0C4)) return 'A';
if (n.Between(0XB0C5, 0XB2C0)) return 'B';
if (n.Between(0xB2C1, 0xB4ED)) return 'C';
if (n.Between(0xB4EE, 0xB6E9)) return 'D';
if (n.Between(0xB6EA, 0xB7A1)) return 'E';
if (n.Between(0xB7A2, 0xB8c0)) return 'F';
if (n.Between(0xB8C1, 0xB9FD)) return 'G';
if (n.Between(0xB9FE, 0xBBF6)) return 'H';
if (n.Between(0xBBF7, 0xBFA5)) return 'J';
if (n.Between(0xBFA6, 0xC0AB)) return 'K';
if (n.Between(0xC0AC, 0xC2E7)) return 'L';
if (n.Between(0xC2E8, 0xC4C2)) return 'M';
if (n.Between(0xC4C3, 0xC5B5)) return 'N';
if (n.Between(0xC5B6, 0xC5BD)) return 'O';
if (n.Between(0xC5BE, 0xC6D9)) return 'P';
if (n.Between(0xC6DA, 0xC8BA)) return 'Q';
if (n.Between(0xC8BB, 0xC8F5)) return 'R';
if (n.Between(0xC8F6, 0xCBF9)) return 'S';
if (n.Between(0xCBFA, 0xCDD9)) return 'T';
if (n.Between(0xCDDA, 0xCEF3)) return 'W';
if (n.Between(0xCEF4, 0xD188)) return 'X';
if (n.Between(0xD1B9, 0xD4D0)) return 'Y';
if (n.Between(0xD4D1, 0xD7F9)) return 'Z';
return '\0';
}
......
......@@ -150,6 +150,16 @@ namespace Tools.Properties {
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap 删除 {
get {
object obj = ResourceManager.GetObject("删除", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
......@@ -160,6 +170,16 @@ namespace Tools.Properties {
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap 复制 {
get {
object obj = ResourceManager.GetObject("复制", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
......@@ -200,6 +220,16 @@ namespace Tools.Properties {
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap 新增 {
get {
object obj = ResourceManager.GetObject("新增", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
......
......@@ -145,9 +145,15 @@
<data name="分析" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\分析.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="删除" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\删 除.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="加载" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\加载.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="复制" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\复制.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="实体类" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\实体类.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
......@@ -160,6 +166,9 @@
<data name="数据库" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\数据库.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="新增" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\新增.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="暂存" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\暂存.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
......
Tools/Resources/sql.png

1.15 KB | W: | H:

Tools/Resources/sql.png

725 Bytes | W: | H:

Tools/Resources/sql.png
Tools/Resources/sql.png
Tools/Resources/sql.png
Tools/Resources/sql.png
  • 2-up
  • Swipe
  • Onion skin
......@@ -160,6 +160,18 @@
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="UI\wLoginPwd.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="UI\wLoginPwd.Designer.cs">
<DependentUpon>wLoginPwd.cs</DependentUpon>
</Compile>
<Compile Include="UI\wModuleManager.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="UI\wModuleManager.Designer.cs">
<DependentUpon>wModuleManager.cs</DependentUpon>
</Compile>
<Compile Include="UI\wMonitorVisit.cs">
<SubType>Form</SubType>
</Compile>
......@@ -178,6 +190,12 @@
<Compile Include="UI\wSysChecker.Designer.cs">
<DependentUpon>wSysChecker.cs</DependentUpon>
</Compile>
<Compile Include="UI\wXmlGenerator.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="UI\wXmlGenerator.Designer.cs">
<DependentUpon>wXmlGenerator.cs</DependentUpon>
</Compile>
<Compile Include="wExtend.cs" />
<Compile Include="wMain.cs">
<SubType>Form</SubType>
......@@ -237,6 +255,12 @@
<EmbeddedResource Include="UI\wDBTools.resx">
<DependentUpon>wDBTools.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="UI\wLoginPwd.resx">
<DependentUpon>wLoginPwd.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="UI\wModuleManager.resx">
<DependentUpon>wModuleManager.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="UI\wMonitorVisit.resx">
<DependentUpon>wMonitorVisit.cs</DependentUpon>
</EmbeddedResource>
......@@ -246,6 +270,9 @@
<EmbeddedResource Include="UI\wSysChecker.resx">
<DependentUpon>wSysChecker.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="UI\wXmlGenerator.resx">
<DependentUpon>wXmlGenerator.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="wMain.resx">
<DependentUpon>wMain.cs</DependentUpon>
<SubType>Designer</SubType>
......@@ -291,9 +318,6 @@
<ItemGroup>
<None Include="Resources\数据库.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\sql.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\类.png" />
</ItemGroup>
......@@ -334,5 +358,17 @@
<ItemGroup>
<None Include="Resources\node_audit.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\新增.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\复制.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\删 除.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\SQL.png" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
\ No newline at end of file
......@@ -130,7 +130,7 @@ namespace Tools.UI
string original_dhash = "";
string original_phash = "";
//图片库路径
string imgPath = $@"F:\图片查询\ImageSearch-master\images";
string imgPath = $@"F:\ImageSearch\images";
//预处理缓存
DataTable dtHash = null;
......@@ -319,7 +319,7 @@ namespace Tools.UI
}
/// <summary>
///
/// 图片查询-工具类
/// </summary>
public static class ImageSearchUtil
{
......@@ -430,8 +430,6 @@ namespace Tools.UI
}
}
/// <summary>
/// 图片指纹生成
/// </summary>
......@@ -481,7 +479,7 @@ namespace Tools.UI
{
for (int j = 0; j < size; j++)
{
feature += matrix[i, j] > matrix[i + 1, j] ? "1" : "0";
feature += matrix[i, j] < matrix[i + 1, j] ? "1" : "0";
}
}
return feature;
......
namespace Tools.UI
{
partial class wLoginPwd
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.tbPassword = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.btnDecrypt = new System.Windows.Forms.Button();
this.tbResult = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// tbPassword
//
this.tbPassword.Location = new System.Drawing.Point(116, 51);
this.tbPassword.Name = "tbPassword";
this.tbPassword.Size = new System.Drawing.Size(171, 21);
this.tbPassword.TabIndex = 0;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(81, 54);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(29, 12);
this.label1.TabIndex = 1;
this.label1.Text = "密文";
//
// btnDecrypt
//
this.btnDecrypt.Location = new System.Drawing.Point(116, 78);
this.btnDecrypt.Name = "btnDecrypt";
this.btnDecrypt.Size = new System.Drawing.Size(75, 23);
this.btnDecrypt.TabIndex = 2;
this.btnDecrypt.Text = "解密";
this.btnDecrypt.UseVisualStyleBackColor = true;
this.btnDecrypt.Click += new System.EventHandler(this.btnDecrypt_Click);
//
// tbResult
//
this.tbResult.Location = new System.Drawing.Point(116, 107);
this.tbResult.Name = "tbResult";
this.tbResult.Size = new System.Drawing.Size(171, 21);
this.tbResult.TabIndex = 3;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(81, 110);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(29, 12);
this.label2.TabIndex = 4;
this.label2.Text = "结果";
//
// wLoginPwd
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(377, 213);
this.Controls.Add(this.label2);
this.Controls.Add(this.tbResult);
this.Controls.Add(this.btnDecrypt);
this.Controls.Add(this.label1);
this.Controls.Add(this.tbPassword);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Name = "wLoginPwd";
this.Text = "wLoginPwd";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox tbPassword;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button btnDecrypt;
private System.Windows.Forms.TextBox tbResult;
private System.Windows.Forms.Label label2;
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
//
using Tools.MyCommon;
using Tools.MyUtils;
namespace Tools.UI
{
public partial class wLoginPwd : wBasic
{
/// <summary>
/// 密文
/// </summary>
string Password => this.tbPassword.Text.Trim();
/// <summary>
/// 结果
/// </summary>
string Result
{
get => this.tbResult.Text.Trim();
set => this.tbResult.Text = value;
}
public wLoginPwd()
{
InitializeComponent();
}
/// <summary>
/// 按钮事件:解密
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnDecrypt_Click(object sender, EventArgs e)
{
//解密
this.Result = Utils.DecryptString(this.Password);
//获取焦点,并选中文本
this.tbResult.Focus();
this.tbResult.SelectAll();
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
\ No newline at end of file
namespace Tools.UI
{
partial class wModuleManager
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(wModuleManager));
this.toolStrip1 = new System.Windows.Forms.ToolStrip();
this.tslDbLinkString = new System.Windows.Forms.ToolStripLabel();
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.tvModules = new System.Windows.Forms.TreeView();
this.imgList5 = new System.Windows.Forms.ImageList(this.components);
this.panelMHeader = new System.Windows.Forms.Panel();
this.tbSearch = new System.Windows.Forms.TextBox();
this.label13 = new System.Windows.Forms.Label();
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.dgvDetail = new System.Windows.Forms.DataGridView();
this.cmsDetail = new System.Windows.Forms.ContextMenuStrip(this.components);
this.tsmiAdd = new System.Windows.Forms.ToolStripMenuItem();
this.tsmiCopy = new System.Windows.Forms.ToolStripMenuItem();
this.tsmiDel = new System.Windows.Forms.ToolStripMenuItem();
this.tsFuncInfo = new System.Windows.Forms.ToolStrip();
this.toolStripLabel2 = new System.Windows.Forms.ToolStripLabel();
this.tsBaseInfo = new System.Windows.Forms.ToolStrip();
this.toolStripLabel3 = new System.Windows.Forms.ToolStripLabel();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label();
this.label5 = new System.Windows.Forms.Label();
this.label6 = new System.Windows.Forms.Label();
this.label7 = new System.Windows.Forms.Label();
this.label8 = new System.Windows.Forms.Label();
this.label9 = new System.Windows.Forms.Label();
this.label10 = new System.Windows.Forms.Label();
this.label11 = new System.Windows.Forms.Label();
this.label12 = new System.Windows.Forms.Label();
this.tbName = new System.Windows.Forms.TextBox();
this.tbBusinessName = new System.Windows.Forms.TextBox();
this.tbStringID = new System.Windows.Forms.TextBox();
this.tbDocType = new System.Windows.Forms.TextBox();
this.tbLevelNum = new System.Windows.Forms.TextBox();
this.tbIndex = new System.Windows.Forms.TextBox();
this.tbIcoIndex = new System.Windows.Forms.TextBox();
this.tbType = new System.Windows.Forms.TextBox();
this.tbProductBarCodeType = new System.Windows.Forms.TextBox();
this.ckCanPassLevelReport = new System.Windows.Forms.CheckBox();
this.tbSysCode = new System.Windows.Forms.TextBox();
this.tbPrevID = new System.Windows.Forms.TextBox();
this.tsbAdd = new System.Windows.Forms.ToolStripButton();
this.tsbCopy = new System.Windows.Forms.ToolStripButton();
this.tsbDel = new System.Windows.Forms.ToolStripButton();
this.tsbSave = new System.Windows.Forms.ToolStripButton();
this.tsbGenSQL = new System.Windows.Forms.ToolStripButton();
this.tsbDbSetting = new System.Windows.Forms.ToolStripButton();
this.toolStrip1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
this.splitContainer1.Panel1.SuspendLayout();
this.splitContainer1.Panel2.SuspendLayout();
this.splitContainer1.SuspendLayout();
this.panelMHeader.SuspendLayout();
this.tableLayoutPanel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.dgvDetail)).BeginInit();
this.cmsDetail.SuspendLayout();
this.tsFuncInfo.SuspendLayout();
this.tsBaseInfo.SuspendLayout();
this.SuspendLayout();
//
// toolStrip1
//
this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.tsbAdd,
this.tsbCopy,
this.tsbDel,
this.tsbSave,
this.tsbGenSQL,
this.tsbDbSetting,
this.tslDbLinkString});
this.toolStrip1.Location = new System.Drawing.Point(0, 0);
this.toolStrip1.Name = "toolStrip1";
this.toolStrip1.Size = new System.Drawing.Size(979, 25);
this.toolStrip1.TabIndex = 0;
this.toolStrip1.Text = "toolStrip1";
//
// tslDbLinkString
//
this.tslDbLinkString.AutoSize = false;
this.tslDbLinkString.Font = new System.Drawing.Font("Microsoft YaHei UI", 7.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.tslDbLinkString.ForeColor = System.Drawing.Color.Green;
this.tslDbLinkString.Name = "tslDbLinkString";
this.tslDbLinkString.Size = new System.Drawing.Size(150, 22);
this.tslDbLinkString.Text = "--请先选择数据库链接--";
this.tslDbLinkString.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// splitContainer1
//
this.splitContainer1.BackColor = System.Drawing.Color.LightSkyBlue;
this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer1.Location = new System.Drawing.Point(0, 25);
this.splitContainer1.Name = "splitContainer1";
//
// splitContainer1.Panel1
//
this.splitContainer1.Panel1.BackColor = System.Drawing.SystemColors.Control;
this.splitContainer1.Panel1.Controls.Add(this.tvModules);
this.splitContainer1.Panel1.Controls.Add(this.panelMHeader);
//
// splitContainer1.Panel2
//
this.splitContainer1.Panel2.BackColor = System.Drawing.SystemColors.Control;
this.splitContainer1.Panel2.Controls.Add(this.tableLayoutPanel1);
this.splitContainer1.Size = new System.Drawing.Size(979, 541);
this.splitContainer1.SplitterDistance = 259;
this.splitContainer1.SplitterWidth = 6;
this.splitContainer1.TabIndex = 1;
//
// tvModules
//
this.tvModules.Dock = System.Windows.Forms.DockStyle.Fill;
this.tvModules.ImageIndex = 0;
this.tvModules.ImageList = this.imgList5;
this.tvModules.Location = new System.Drawing.Point(0, 39);
this.tvModules.Name = "tvModules";
this.tvModules.SelectedImageIndex = 0;
this.tvModules.Size = new System.Drawing.Size(259, 502);
this.tvModules.TabIndex = 1;
//
// imgList5
//
this.imgList5.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imgList5.ImageStream")));
this.imgList5.TransparentColor = System.Drawing.Color.Transparent;
this.imgList5.Images.SetKeyName(0, "tv5-gray.png");
this.imgList5.Images.SetKeyName(1, "tv5-red.png");
//
// panelMHeader
//
this.panelMHeader.BackColor = System.Drawing.SystemColors.Control;
this.panelMHeader.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.panelMHeader.Controls.Add(this.tbSearch);
this.panelMHeader.Controls.Add(this.label13);
this.panelMHeader.Dock = System.Windows.Forms.DockStyle.Top;
this.panelMHeader.Location = new System.Drawing.Point(0, 0);
this.panelMHeader.Name = "panelMHeader";
this.panelMHeader.Size = new System.Drawing.Size(259, 39);
this.panelMHeader.TabIndex = 0;
//
// tbSearch
//
this.tbSearch.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.tbSearch.Location = new System.Drawing.Point(52, 9);
this.tbSearch.Name = "tbSearch";
this.tbSearch.Size = new System.Drawing.Size(189, 21);
this.tbSearch.TabIndex = 1;
//
// label13
//
this.label13.AutoSize = true;
this.label13.Location = new System.Drawing.Point(5, 12);
this.label13.Name = "label13";
this.label13.Size = new System.Drawing.Size(41, 12);
this.label13.TabIndex = 0;
this.label13.Text = "查询:";
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.ColumnCount = 8;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 75F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 75F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 75F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 75F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
this.tableLayoutPanel1.Controls.Add(this.dgvDetail, 0, 5);
this.tableLayoutPanel1.Controls.Add(this.tsFuncInfo, 0, 4);
this.tableLayoutPanel1.Controls.Add(this.tsBaseInfo, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.label1, 0, 1);
this.tableLayoutPanel1.Controls.Add(this.label2, 0, 2);
this.tableLayoutPanel1.Controls.Add(this.label3, 0, 3);
this.tableLayoutPanel1.Controls.Add(this.label4, 2, 1);
this.tableLayoutPanel1.Controls.Add(this.label5, 2, 2);
this.tableLayoutPanel1.Controls.Add(this.label6, 2, 3);
this.tableLayoutPanel1.Controls.Add(this.label7, 4, 1);
this.tableLayoutPanel1.Controls.Add(this.label8, 4, 2);
this.tableLayoutPanel1.Controls.Add(this.label9, 4, 3);
this.tableLayoutPanel1.Controls.Add(this.label10, 6, 1);
this.tableLayoutPanel1.Controls.Add(this.label11, 6, 2);
this.tableLayoutPanel1.Controls.Add(this.label12, 6, 3);
this.tableLayoutPanel1.Controls.Add(this.tbName, 1, 1);
this.tableLayoutPanel1.Controls.Add(this.tbBusinessName, 5, 1);
this.tableLayoutPanel1.Controls.Add(this.tbStringID, 1, 2);
this.tableLayoutPanel1.Controls.Add(this.tbDocType, 7, 1);
this.tableLayoutPanel1.Controls.Add(this.tbLevelNum, 3, 2);
this.tableLayoutPanel1.Controls.Add(this.tbIndex, 5, 2);
this.tableLayoutPanel1.Controls.Add(this.tbIcoIndex, 7, 2);
this.tableLayoutPanel1.Controls.Add(this.tbType, 1, 3);
this.tableLayoutPanel1.Controls.Add(this.tbProductBarCodeType, 3, 3);
this.tableLayoutPanel1.Controls.Add(this.ckCanPassLevelReport, 5, 3);
this.tableLayoutPanel1.Controls.Add(this.tbSysCode, 7, 3);
this.tableLayoutPanel1.Controls.Add(this.tbPrevID, 3, 1);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 8;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 27F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 27F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 27F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 27F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 27F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 27F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 27F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel1.Size = new System.Drawing.Size(714, 541);
this.tableLayoutPanel1.TabIndex = 1;
//
// dgvDetail
//
this.dgvDetail.BackgroundColor = System.Drawing.SystemColors.Window;
this.dgvDetail.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.tableLayoutPanel1.SetColumnSpan(this.dgvDetail, 8);
this.dgvDetail.ContextMenuStrip = this.cmsDetail;
this.dgvDetail.Dock = System.Windows.Forms.DockStyle.Fill;
this.dgvDetail.Location = new System.Drawing.Point(3, 138);
this.dgvDetail.Name = "dgvDetail";
this.tableLayoutPanel1.SetRowSpan(this.dgvDetail, 3);
this.dgvDetail.RowTemplate.Height = 23;
this.dgvDetail.Size = new System.Drawing.Size(708, 400);
this.dgvDetail.TabIndex = 1;
//
// cmsDetail
//
this.cmsDetail.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.tsmiAdd,
this.tsmiCopy,
this.tsmiDel});
this.cmsDetail.Name = "cmsDetail";
this.cmsDetail.Size = new System.Drawing.Size(101, 70);
//
// tsmiAdd
//
this.tsmiAdd.Name = "tsmiAdd";
this.tsmiAdd.Size = new System.Drawing.Size(100, 22);
this.tsmiAdd.Text = "増行";
//
// tsmiCopy
//
this.tsmiCopy.Name = "tsmiCopy";
this.tsmiCopy.Size = new System.Drawing.Size(100, 22);
this.tsmiCopy.Text = "复制";
//
// tsmiDel
//
this.tsmiDel.Name = "tsmiDel";
this.tsmiDel.Size = new System.Drawing.Size(100, 22);
this.tsmiDel.Text = "删行";
//
// tsFuncInfo
//
this.tableLayoutPanel1.SetColumnSpan(this.tsFuncInfo, 8);
this.tsFuncInfo.Dock = System.Windows.Forms.DockStyle.Fill;
this.tsFuncInfo.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripLabel2});
this.tsFuncInfo.Location = new System.Drawing.Point(0, 108);
this.tsFuncInfo.Name = "tsFuncInfo";
this.tsFuncInfo.Size = new System.Drawing.Size(714, 27);
this.tsFuncInfo.TabIndex = 1;
this.tsFuncInfo.Text = "toolStrip3";
//
// toolStripLabel2
//
this.toolStripLabel2.Name = "toolStripLabel2";
this.toolStripLabel2.Size = new System.Drawing.Size(56, 24);
this.toolStripLabel2.Text = "功能信息";
//
// tsBaseInfo
//
this.tableLayoutPanel1.SetColumnSpan(this.tsBaseInfo, 8);
this.tsBaseInfo.Dock = System.Windows.Forms.DockStyle.Fill;
this.tsBaseInfo.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripLabel3});
this.tsBaseInfo.Location = new System.Drawing.Point(0, 0);
this.tsBaseInfo.Name = "tsBaseInfo";
this.tsBaseInfo.Size = new System.Drawing.Size(714, 27);
this.tsBaseInfo.TabIndex = 0;
this.tsBaseInfo.Text = "toolStrip2";
//
// toolStripLabel3
//
this.toolStripLabel3.Name = "toolStripLabel3";
this.toolStripLabel3.Size = new System.Drawing.Size(56, 24);
this.toolStripLabel3.Text = "基本信息";
//
// label1
//
this.label1.AutoSize = true;
this.label1.Dock = System.Windows.Forms.DockStyle.Fill;
this.label1.Location = new System.Drawing.Point(3, 27);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(69, 27);
this.label1.TabIndex = 2;
this.label1.Text = "模块名称";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Dock = System.Windows.Forms.DockStyle.Fill;
this.label2.Location = new System.Drawing.Point(3, 54);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(69, 27);
this.label2.TabIndex = 3;
this.label2.Text = "字符串ID";
this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// label3
//
this.label3.AutoSize = true;
this.label3.Dock = System.Windows.Forms.DockStyle.Fill;
this.label3.Location = new System.Drawing.Point(3, 81);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(69, 27);
this.label3.TabIndex = 4;
this.label3.Text = "类 型";
this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// label4
//
this.label4.AutoSize = true;
this.label4.Dock = System.Windows.Forms.DockStyle.Fill;
this.label4.Location = new System.Drawing.Point(181, 27);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(69, 27);
this.label4.TabIndex = 5;
this.label4.Text = "归属目录";
this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// label5
//
this.label5.AutoSize = true;
this.label5.Dock = System.Windows.Forms.DockStyle.Fill;
this.label5.Location = new System.Drawing.Point(181, 54);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(69, 27);
this.label5.TabIndex = 6;
this.label5.Text = "层级编号";
this.label5.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// label6
//
this.label6.AutoSize = true;
this.label6.Dock = System.Windows.Forms.DockStyle.Fill;
this.label6.Location = new System.Drawing.Point(181, 81);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(69, 27);
this.label6.TabIndex = 7;
this.label6.Text = "条码类型";
this.label6.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// label7
//
this.label7.AutoSize = true;
this.label7.Dock = System.Windows.Forms.DockStyle.Fill;
this.label7.Location = new System.Drawing.Point(359, 27);
this.label7.Name = "label7";
this.label7.Size = new System.Drawing.Size(69, 27);
this.label7.TabIndex = 8;
this.label7.Text = "业 务 类";
this.label7.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// label8
//
this.label8.AutoSize = true;
this.label8.Dock = System.Windows.Forms.DockStyle.Fill;
this.label8.Location = new System.Drawing.Point(359, 54);
this.label8.Name = "label8";
this.label8.Size = new System.Drawing.Size(69, 27);
this.label8.TabIndex = 9;
this.label8.Text = "序 号";
this.label8.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// label9
//
this.label9.AutoSize = true;
this.label9.Dock = System.Windows.Forms.DockStyle.Fill;
this.label9.Location = new System.Drawing.Point(359, 81);
this.label9.Name = "label9";
this.label9.Size = new System.Drawing.Size(69, 27);
this.label9.TabIndex = 10;
this.label9.Text = "跨级报表";
this.label9.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// label10
//
this.label10.AutoSize = true;
this.label10.Dock = System.Windows.Forms.DockStyle.Fill;
this.label10.Location = new System.Drawing.Point(537, 27);
this.label10.Name = "label10";
this.label10.Size = new System.Drawing.Size(69, 27);
this.label10.TabIndex = 11;
this.label10.Text = "枚 举 值";
this.label10.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// label11
//
this.label11.AutoSize = true;
this.label11.Dock = System.Windows.Forms.DockStyle.Fill;
this.label11.Location = new System.Drawing.Point(537, 54);
this.label11.Name = "label11";
this.label11.Size = new System.Drawing.Size(69, 27);
this.label11.TabIndex = 12;
this.label11.Text = "图标编号";
this.label11.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// label12
//
this.label12.AutoSize = true;
this.label12.Dock = System.Windows.Forms.DockStyle.Fill;
this.label12.Location = new System.Drawing.Point(537, 81);
this.label12.Name = "label12";
this.label12.Size = new System.Drawing.Size(69, 27);
this.label12.TabIndex = 13;
this.label12.Text = "系统归属";
this.label12.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// tbName
//
this.tbName.Dock = System.Windows.Forms.DockStyle.Fill;
this.tbName.Location = new System.Drawing.Point(78, 30);
this.tbName.Name = "tbName";
this.tbName.Size = new System.Drawing.Size(97, 21);
this.tbName.TabIndex = 14;
//
// tbBusinessName
//
this.tbBusinessName.Dock = System.Windows.Forms.DockStyle.Fill;
this.tbBusinessName.Location = new System.Drawing.Point(434, 30);
this.tbBusinessName.Name = "tbBusinessName";
this.tbBusinessName.ReadOnly = true;
this.tbBusinessName.Size = new System.Drawing.Size(97, 21);
this.tbBusinessName.TabIndex = 16;
//
// tbStringID
//
this.tbStringID.Dock = System.Windows.Forms.DockStyle.Fill;
this.tbStringID.Location = new System.Drawing.Point(78, 57);
this.tbStringID.Name = "tbStringID";
this.tbStringID.Size = new System.Drawing.Size(97, 21);
this.tbStringID.TabIndex = 18;
//
// tbDocType
//
this.tbDocType.Dock = System.Windows.Forms.DockStyle.Fill;
this.tbDocType.Location = new System.Drawing.Point(612, 30);
this.tbDocType.Name = "tbDocType";
this.tbDocType.Size = new System.Drawing.Size(99, 21);
this.tbDocType.TabIndex = 19;
//
// tbLevelNum
//
this.tbLevelNum.Dock = System.Windows.Forms.DockStyle.Fill;
this.tbLevelNum.Location = new System.Drawing.Point(256, 57);
this.tbLevelNum.Name = "tbLevelNum";
this.tbLevelNum.Size = new System.Drawing.Size(97, 21);
this.tbLevelNum.TabIndex = 20;
//
// tbIndex
//
this.tbIndex.Dock = System.Windows.Forms.DockStyle.Fill;
this.tbIndex.Location = new System.Drawing.Point(434, 57);
this.tbIndex.Name = "tbIndex";
this.tbIndex.Size = new System.Drawing.Size(97, 21);
this.tbIndex.TabIndex = 21;
//
// tbIcoIndex
//
this.tbIcoIndex.Dock = System.Windows.Forms.DockStyle.Fill;
this.tbIcoIndex.Location = new System.Drawing.Point(612, 57);
this.tbIcoIndex.Name = "tbIcoIndex";
this.tbIcoIndex.Size = new System.Drawing.Size(99, 21);
this.tbIcoIndex.TabIndex = 22;
//
// tbType
//
this.tbType.Dock = System.Windows.Forms.DockStyle.Fill;
this.tbType.Location = new System.Drawing.Point(78, 84);
this.tbType.Name = "tbType";
this.tbType.ReadOnly = true;
this.tbType.Size = new System.Drawing.Size(97, 21);
this.tbType.TabIndex = 23;
//
// tbProductBarCodeType
//
this.tbProductBarCodeType.Dock = System.Windows.Forms.DockStyle.Fill;
this.tbProductBarCodeType.Location = new System.Drawing.Point(256, 84);
this.tbProductBarCodeType.Name = "tbProductBarCodeType";
this.tbProductBarCodeType.ReadOnly = true;
this.tbProductBarCodeType.Size = new System.Drawing.Size(97, 21);
this.tbProductBarCodeType.TabIndex = 24;
//
// ckCanPassLevelReport
//
this.ckCanPassLevelReport.AutoSize = true;
this.ckCanPassLevelReport.Dock = System.Windows.Forms.DockStyle.Fill;
this.ckCanPassLevelReport.Enabled = false;
this.ckCanPassLevelReport.Location = new System.Drawing.Point(434, 84);
this.ckCanPassLevelReport.Name = "ckCanPassLevelReport";
this.ckCanPassLevelReport.Size = new System.Drawing.Size(97, 21);
this.ckCanPassLevelReport.TabIndex = 25;
this.ckCanPassLevelReport.UseVisualStyleBackColor = true;
//
// tbSysCode
//
this.tbSysCode.Dock = System.Windows.Forms.DockStyle.Fill;
this.tbSysCode.Location = new System.Drawing.Point(612, 84);
this.tbSysCode.Name = "tbSysCode";
this.tbSysCode.Size = new System.Drawing.Size(99, 21);
this.tbSysCode.TabIndex = 26;
//
// tbPrevID
//
this.tbPrevID.Dock = System.Windows.Forms.DockStyle.Fill;
this.tbPrevID.Location = new System.Drawing.Point(256, 30);
this.tbPrevID.Name = "tbPrevID";
this.tbPrevID.Size = new System.Drawing.Size(97, 21);
this.tbPrevID.TabIndex = 28;
//
// tsbAdd
//
this.tsbAdd.Image = global::Tools.Properties.Resources.新增;
this.tsbAdd.ImageTransparentColor = System.Drawing.Color.Magenta;
this.tsbAdd.Name = "tsbAdd";
this.tsbAdd.Size = new System.Drawing.Size(52, 22);
this.tsbAdd.Text = "新增";
//
// tsbCopy
//
this.tsbCopy.Image = global::Tools.Properties.Resources.复制;
this.tsbCopy.ImageTransparentColor = System.Drawing.Color.Magenta;
this.tsbCopy.Name = "tsbCopy";
this.tsbCopy.Size = new System.Drawing.Size(52, 22);
this.tsbCopy.Text = "复制";
//
// tsbDel
//
this.tsbDel.Image = global::Tools.Properties.Resources.删除;
this.tsbDel.ImageTransparentColor = System.Drawing.Color.Magenta;
this.tsbDel.Name = "tsbDel";
this.tsbDel.Size = new System.Drawing.Size(52, 22);
this.tsbDel.Text = "删除";
//
// tsbSave
//
this.tsbSave.Image = global::Tools.Properties.Resources.保存;
this.tsbSave.ImageTransparentColor = System.Drawing.Color.Magenta;
this.tsbSave.Name = "tsbSave";
this.tsbSave.Size = new System.Drawing.Size(52, 22);
this.tsbSave.Text = "保存";
//
// tsbGenSQL
//
this.tsbGenSQL.Image = global::Tools.Properties.Resources.sql;
this.tsbGenSQL.ImageTransparentColor = System.Drawing.Color.Magenta;
this.tsbGenSQL.Name = "tsbGenSQL";
this.tsbGenSQL.Size = new System.Drawing.Size(99, 22);
this.tsbGenSQL.Text = "生成SQL脚本";
//
// tsbDbSetting
//
this.tsbDbSetting.Image = global::Tools.Properties.Resources.数据库;
this.tsbDbSetting.ImageTransparentColor = System.Drawing.Color.Magenta;
this.tsbDbSetting.Name = "tsbDbSetting";
this.tsbDbSetting.Size = new System.Drawing.Size(64, 22);
this.tsbDbSetting.Text = "数据库";
//
// wModuleManager
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(979, 566);
this.Controls.Add(this.splitContainer1);
this.Controls.Add(this.toolStrip1);
this.MinimumSize = new System.Drawing.Size(982, 605);
this.Name = "wModuleManager";
this.Text = "模块管理";
this.Load += new System.EventHandler(this.wModuleManager_Load);
this.toolStrip1.ResumeLayout(false);
this.toolStrip1.PerformLayout();
this.splitContainer1.Panel1.ResumeLayout(false);
this.splitContainer1.Panel2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
this.splitContainer1.ResumeLayout(false);
this.panelMHeader.ResumeLayout(false);
this.panelMHeader.PerformLayout();
this.tableLayoutPanel1.ResumeLayout(false);
this.tableLayoutPanel1.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.dgvDetail)).EndInit();
this.cmsDetail.ResumeLayout(false);
this.tsFuncInfo.ResumeLayout(false);
this.tsFuncInfo.PerformLayout();
this.tsBaseInfo.ResumeLayout(false);
this.tsBaseInfo.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.ToolStrip toolStrip1;
private System.Windows.Forms.SplitContainer splitContainer1;
private System.Windows.Forms.TreeView tvModules;
private System.Windows.Forms.Panel panelMHeader;
private System.Windows.Forms.ToolStripButton tsbAdd;
private System.Windows.Forms.ToolStripButton tsbCopy;
private System.Windows.Forms.ToolStripButton tsbDbSetting;
private System.Windows.Forms.ToolStripLabel tslDbLinkString;
private System.Windows.Forms.TextBox tbSearch;
private System.Windows.Forms.Label label13;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.DataGridView dgvDetail;
private System.Windows.Forms.ToolStrip tsFuncInfo;
private System.Windows.Forms.ToolStripLabel toolStripLabel2;
private System.Windows.Forms.ToolStrip tsBaseInfo;
private System.Windows.Forms.ToolStripLabel toolStripLabel3;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.Label label6;
private System.Windows.Forms.Label label7;
private System.Windows.Forms.Label label8;
private System.Windows.Forms.Label label9;
private System.Windows.Forms.Label label10;
private System.Windows.Forms.Label label11;
private System.Windows.Forms.Label label12;
private System.Windows.Forms.TextBox tbName;
private System.Windows.Forms.TextBox tbBusinessName;
private System.Windows.Forms.TextBox tbStringID;
private System.Windows.Forms.TextBox tbDocType;
private System.Windows.Forms.TextBox tbLevelNum;
private System.Windows.Forms.TextBox tbIndex;
private System.Windows.Forms.TextBox tbIcoIndex;
private System.Windows.Forms.TextBox tbType;
private System.Windows.Forms.TextBox tbProductBarCodeType;
private System.Windows.Forms.CheckBox ckCanPassLevelReport;
private System.Windows.Forms.TextBox tbSysCode;
private System.Windows.Forms.TextBox tbPrevID;
private System.Windows.Forms.ToolStripButton tsbSave;
private System.Windows.Forms.ImageList imgList5;
private System.Windows.Forms.ToolStripButton tsbDel;
private System.Windows.Forms.ContextMenuStrip cmsDetail;
private System.Windows.Forms.ToolStripMenuItem tsmiAdd;
private System.Windows.Forms.ToolStripMenuItem tsmiDel;
private System.Windows.Forms.ToolStripMenuItem tsmiCopy;
private System.Windows.Forms.ToolStripButton tsbGenSQL;
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
//
using Tools.MyCommon;
using Tools.MyUtils;
using Tools.MyData;
using System.Reflection;
namespace Tools.UI
{
public partial class wModuleManager : wEditBasic
{
/// <summary>
/// 树形图-数据源
/// </summary>
DataTable _dtModel = null;
/// <summary>
/// 明细表格-数据源
/// </summary>
DataTable _dtDetail = null;
#region 树节点-相关属性
/// <summary>
/// 树形图-父键列
/// </summary>
string ParentColumn => "PrevID";
/// <summary>
/// 树形图-主键列
/// </summary>
string NodeKeyColumn => "ID";
/// <summary>
/// 树形图-名称列
/// </summary>
string NodeTextColumn => "Name";
#endregion
public wModuleManager()
{
InitializeComponent();
}
private void wModuleManager_Load(object sender, EventArgs e)
{
//工具栏事件
this.tsbAdd.Click += TsbAdd_Click;
this.tsbCopy.Click += TsbCopy_Click;
this.tsbDel.Click += TsbDel_Click;
this.tsbSave.Click += TsbSave_Click;
this.tsbGenSQL.Click += TsbGenSQL_Click;
this.tsbDbSetting.Click += TsbDbSetting_Click;
//上下文菜单事件
this.tsmiAdd.Click += TsmiAdd_Click;
this.tsmiCopy.Click += TsmiCopy_Click;
this.tsmiDel.Click += TsmiDel_Click;
}
public override void InitData()
{
base.InitData();
this.ModuleTableList = new List<TQuery> {
new TQuery("SysBusinessModel"),
new TQuery("SysFunction"),
};
this._ds = this._db.GetData(this.ModuleTableList, true);
this._dtModel = this._ds.Tables["SysBusinessModel"];
this._dtDetail = this._ds.Tables["SysFunction"];
}
public override void InitUI()
{
base.InitUI();
//绑定明细数据源
this.dgvDetail.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
this.dgvDetail.AllowUserToAddRows = false;
this.dgvDetail.DataSource = this._dtDetail.DefaultView;
//初始化树形图
this.InitTreeView();
//模块查询
this.tbSearch.TextChanged += TbSearch_TextChanged;
//输入模块名称,自动生成字符串ID
this.tbName.TextChanged += TbName_TextChanged;
}
#region 工具栏事件
private void TsbDbSetting_Click(object sender, EventArgs e)
{
var frm = new wDbSetting(this.tslDbLinkString);
if (frm.ShowDialog() == DialogResult.OK)
{
this.InitDBHelper(frm.LinkModel);
this.InitData();
this.InitUI();
}
}
private void TsbAdd_Click(object sender, EventArgs e)
{
this.AddNode();
}
private void TsbCopy_Click(object sender, EventArgs e)
{
//复制节点
var key = this.AddNode(IsCopy: true);
//复制功能表
var dt = this._dtDetail;
var rows = dt.Select($"ModelID = {key}");
foreach (DataRow r in rows)
{
var drNew = dt.GetNewRow();
Utils.CopyRow(r, drNew, new List<string> { "ModelID" });
dt.Rows.Add(drNew);
}
}
private void TsbDel_Click(object sender, EventArgs e)
{
this.DeleteNode();
}
private void TsbSave_Click(object sender, EventArgs e)
{
this.Save();
}
private void TsbGenSQL_Click(object sender, EventArgs e)
{
//模块表
DataRow drMaster = this.GetCurrentNodeRow();
var model = Utils.GenInsertSQL(drMaster);
//功能表
var rows = this._dtDetail.DefaultView.Cast<DataRowView>().Select(r => r.Row);
var detail = Utils.GenInsertSQL(rows.ToArray());
//生成结果
var result = $"IF NOT EXISTS(SELECT 1 FROM SysBusinessModel WHERE Name = '{this.tbName.Text}')\r\nBEGIN\r\n{model}\r\nDECLARE @ModelID INT;\r\nSET @ModelID=SCOPE_IDENTITY();\r\n{detail}\r\nEND";
//显示结果
Utils.Tip(result, 800, 600);
}
#endregion
#region 上下文菜单事件
private void TsmiAdd_Click(object sender, EventArgs e)
{
this._dtDetail.Rows.Add(this._dtDetail.GetNewRow());
}
private void TsmiCopy_Click(object sender, EventArgs e)
{
for (int i = 0; i < dgvDetail.SelectedRows.Count; i++)
{
int RowIndex = dgvDetail.SelectedRows[i].Index;
DataRow drNew = this._dtDetail.NewRow();
Utils.CopyRow(this._dtDetail.DefaultView[RowIndex].Row, drNew); //不复制ID列
this._dtDetail.Rows.Add(drNew);
}
}
private void TsmiDel_Click(object sender, EventArgs e)
{
var RowIndexList = from row in dgvDetail.SelectedRows
.Cast<DataGridViewRow>()
orderby row.Index descending //倒序排序
select row.Index;
RowIndexList.ToList().ForEach(i => this._dtDetail.DefaultView[i].Delete());
}
#endregion
#region 树结构处理:此处处理具有通用性,可为后续树控件提取做参考
/// <summary>
/// 树形图-初始化
/// </summary>
/// <param name="tv"></param>
/// <param name="dt"></param>
private void InitTreeView()
{
//初始化树节点
this.InitTreeNode(this.tvModules.Nodes, "0");
//添加选择后事件
this.tvModules.AfterSelect += Tv_AfterSelect;
//默认展开设置
if (this.tvModules.Nodes.Count > 0)
{
this.tvModules.Nodes[0].Expand();
if (this.tvModules.Nodes[0].Nodes.Count > 0)
{
this.tvModules.Nodes[0].Nodes[0].ExpandAll();
}
}
//首次初始化,触发一下事件
if (this.tvModules.Nodes.Count > 0)
{
this.tvModules.SelectedNode = this.tvModules.Nodes[0]; //选中首节点
}
}
/// <summary>
/// 事件-树节点选择后
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Tv_AfterSelect(object sender, TreeViewEventArgs e)
{
var ModelID = e.Node.Name;
var drv = this._dtModel.DefaultView
.Cast<DataRowView>()
.FirstOrDefault(r => r["ID"].ToString().Equals(ModelID));
if (drv != null)
{
//绑定基本信息
this.BindBaseInfo(this.tableLayoutPanel1, drv);
//筛选明细:明细不需要重复绑定
this._dtDetail.DefaultView.RowFilter = $"ModelID = {ModelID}";
}
}
/// <summary>
/// 添加树节点
/// </summary>
/// <param name="IsCopy"></param>
/// <returns></returns>
private string AddNode(bool IsCopy = false)
{
//获取当前节点行
var drCurrent = this.GetCurrentNodeRow();
var ParentKey = drCurrent[this.ParentColumn].ToString();
//创建数据源
int index = this._dtModel.Select($"{NodeTextColumn} like '新模块%'").Length;
string text = $"新模块{index}";
var drNew = this._dtModel.NewRow();
drNew[this.ParentColumn] = ParentKey;
drNew[NodeTextColumn] = text;
if (IsCopy)
{
Utils.CopyRow(drCurrent, drNew, new List<string> { this.ParentColumn, this.NodeKeyColumn, this.NodeTextColumn });
}
this._dtModel.Rows.Add(drNew);
//创建树节点
string key = drNew[this.NodeKeyColumn].ToString();
var ParentNode = this.SearchNode(ParentKey);
var node = new TreeNode(text, 0, 1)
{
Name = key,
};
ParentNode.Nodes.Add(node);
//选中新增节点
this.tvModules.SelectedNode = node;
//返回值
return IsCopy ? drCurrent[this.NodeKeyColumn].ToString() : "";
}
/// <summary>
/// 删除树节点
/// </summary>
public void DeleteNode()
{
var CurrentNode = this.tvModules.SelectedNode;
var ParentNode = CurrentNode.Parent;
if (CurrentNode.Nodes.Count > 0)
{
Utils.Tip($"当前节点[{CurrentNode.Text}]有多个子节点,请先删除子节点!");
return;
}
//删除数据源
var drCurrent = this.GetCurrentNodeRow();
drCurrent?.Delete();
//移除树节点
var nodes = ParentNode == null ? this.tvModules.Nodes : ParentNode.Nodes;
nodes.Remove(CurrentNode);
}
/// <summary>
/// 查找树节点
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
private TreeNode SearchNode(string key)
{
return this.SearchTreeNode(key, this.tvModules.Nodes);
}
/// <summary>
/// 获取当前节点行
/// </summary>
/// <returns></returns>
private DataRow GetCurrentNodeRow()
{
var key = this.tvModules.SelectedNode.Name;
return this._dtModel.Select($"{this.NodeKeyColumn}={key}").FirstOrDefault();
}
/// <summary>
/// 递归:添加树节点
/// </summary>
/// <param name="nodes"></param>
/// <param name="ParentValue"></param>
private void InitTreeNode(TreeNodeCollection nodes, string ParentValue)
{
DataRow[] rows = this._dtModel.Select($"ISNULL({this.ParentColumn}, '0') = '{ParentValue}'");
if (rows.Length == 0)
return;
for (int i = 0; i < rows.Length; i++)
{
if (rows[i].RowState == DataRowState.Deleted)
continue;
var key = rows[i][this.NodeKeyColumn].ToString();
var text = rows[i][this.NodeTextColumn].ToString();
nodes.Add(key, text, 0, 1);
this.InitTreeNode(nodes[i].Nodes, key);
}
}
/// <summary>
/// 递归:查找树节点
/// </summary>
/// <param name="key"></param>
/// <param name="nodes"></param>
/// <returns></returns>
private TreeNode SearchTreeNode(string key, TreeNodeCollection nodes)
{
TreeNode result = null;
foreach (TreeNode n in nodes)
{
result = n.Name.Equals(key) ? n : this.SearchTreeNode(key, n.Nodes);
if (result != null)
break;
}
return result;
}
#endregion
#region 查询功能相关
/// <summary>
/// (查询)文本改变事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TbSearch_TextChanged(object sender, EventArgs e)
{
this.SetTreeNodeBackColor(this.tvModules.Nodes, this.tbSearch.Text.Trim());
}
/// <summary>
/// (查询)设置树节点背景色
/// </summary>
/// <param name="nodes">树节点</param>
/// <param name="SearchText">查询字串</param>
private void SetTreeNodeBackColor(TreeNodeCollection nodes, string SearchText)
{
foreach (TreeNode n in nodes)
{
//查询条件不为空并且包含查询字符,则设置背景色
bool IsSearched = !string.IsNullOrEmpty(SearchText) && n.Text.Contains(SearchText);
n.BackColor = IsSearched ? Color.LightBlue : Color.White;
#region 节点展开与折叠
if (IsSearched)
{
//如果父节点未展开,展开父节点
this.SetParentExpanded(n);
//如果当前节点不是叶子节点,则展开
if (n.Nodes.Count > 0)
n.Expand();
}
else if (n.Parent != null)
{
n.Collapse(); //非根节点,全部折叠
}
#endregion
//递归子节点
this.SetTreeNodeBackColor(n.Nodes, SearchText);
}
}
/// <summary>
/// 展开查询节点的父节点
/// </summary>
/// <param name="n"></param>
private void SetParentExpanded(TreeNode n)
{
while (n.Parent != null)
{
n = n.Parent;
if (!n.IsExpanded)
{
n.Expand();
}
}
}
#endregion
#region 便捷操作:字符串ID-自动生成
private void TbName_TextChanged(object sender, EventArgs e)
{
this.tbStringID.Text = Utils.GetPinyinString(this.tbName.Text);
}
#endregion
}
}
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="toolStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="imgList5.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>634, 18</value>
</metadata>
<data name="imgList5.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADo
CAAAAk1TRnQBSQFMAgEBAgEAAXABAAFwAQABEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
AwABQAMAARADAAEBAQABCAYAAQQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA
AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5
AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA
AWYDAAGZAwABzAIAATMDAAIzAgABMwFmAgABMwGZAgABMwHMAgABMwH/AgABZgMAAWYBMwIAAmYCAAFm
AZkCAAFmAcwCAAFmAf8CAAGZAwABmQEzAgABmQFmAgACmQIAAZkBzAIAAZkB/wIAAcwDAAHMATMCAAHM
AWYCAAHMAZkCAALMAgABzAH/AgAB/wFmAgAB/wGZAgAB/wHMAQABMwH/AgAB/wEAATMBAAEzAQABZgEA
ATMBAAGZAQABMwEAAcwBAAEzAQAB/wEAAf8BMwIAAzMBAAIzAWYBAAIzAZkBAAIzAcwBAAIzAf8BAAEz
AWYCAAEzAWYBMwEAATMCZgEAATMBZgGZAQABMwFmAcwBAAEzAWYB/wEAATMBmQIAATMBmQEzAQABMwGZ
AWYBAAEzApkBAAEzAZkBzAEAATMBmQH/AQABMwHMAgABMwHMATMBAAEzAcwBZgEAATMBzAGZAQABMwLM
AQABMwHMAf8BAAEzAf8BMwEAATMB/wFmAQABMwH/AZkBAAEzAf8BzAEAATMC/wEAAWYDAAFmAQABMwEA
AWYBAAFmAQABZgEAAZkBAAFmAQABzAEAAWYBAAH/AQABZgEzAgABZgIzAQABZgEzAWYBAAFmATMBmQEA
AWYBMwHMAQABZgEzAf8BAAJmAgACZgEzAQADZgEAAmYBmQEAAmYBzAEAAWYBmQIAAWYBmQEzAQABZgGZ
AWYBAAFmApkBAAFmAZkBzAEAAWYBmQH/AQABZgHMAgABZgHMATMBAAFmAcwBmQEAAWYCzAEAAWYBzAH/
AQABZgH/AgABZgH/ATMBAAFmAf8BmQEAAWYB/wHMAQABzAEAAf8BAAH/AQABzAEAApkCAAGZATMBmQEA
AZkBAAGZAQABmQEAAcwBAAGZAwABmQIzAQABmQEAAWYBAAGZATMBzAEAAZkBAAH/AQABmQFmAgABmQFm
ATMBAAGZATMBZgEAAZkBZgGZAQABmQFmAcwBAAGZATMB/wEAApkBMwEAApkBZgEAA5kBAAKZAcwBAAKZ
Af8BAAGZAcwCAAGZAcwBMwEAAWYBzAFmAQABmQHMAZkBAAGZAswBAAGZAcwB/wEAAZkB/wIAAZkB/wEz
AQABmQHMAWYBAAGZAf8BmQEAAZkB/wHMAQABmQL/AQABzAMAAZkBAAEzAQABzAEAAWYBAAHMAQABmQEA
AcwBAAHMAQABmQEzAgABzAIzAQABzAEzAWYBAAHMATMBmQEAAcwBMwHMAQABzAEzAf8BAAHMAWYCAAHM
AWYBMwEAAZkCZgEAAcwBZgGZAQABzAFmAcwBAAGZAWYB/wEAAcwBmQIAAcwBmQEzAQABzAGZAWYBAAHM
ApkBAAHMAZkBzAEAAcwBmQH/AQACzAIAAswBMwEAAswBZgEAAswBmQEAA8wBAALMAf8BAAHMAf8CAAHM
Af8BMwEAAZkB/wFmAQABzAH/AZkBAAHMAf8BzAEAAcwC/wEAAcwBAAEzAQAB/wEAAWYBAAH/AQABmQEA
AcwBMwIAAf8CMwEAAf8BMwFmAQAB/wEzAZkBAAH/ATMBzAEAAf8BMwH/AQAB/wFmAgAB/wFmATMBAAHM
AmYBAAH/AWYBmQEAAf8BZgHMAQABzAFmAf8BAAH/AZkCAAH/AZkBMwEAAf8BmQFmAQAB/wKZAQAB/wGZ
AcwBAAH/AZkB/wEAAf8BzAIAAf8BzAEzAQAB/wHMAWYBAAH/AcwBmQEAAf8CzAEAAf8BzAH/AQAC/wEz
AQABzAH/AWYBAAL/AZkBAAL/AcwBAAJmAf8BAAFmAf8BZgEAAWYC/wEAAf8CZgEAAf8BZgH/AQAC/wFm
AQABIQEAAaUBAANfAQADdwEAA4YBAAOWAQADywEAA7IBAAPXAQAD3QEAA+MBAAPqAQAD8QEAA/gBAAHw
AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD/0MAAfIK8AHyBAABGgpv
ARokAAEHCvABBwQAASUKbwElJAABBwH0CAAB9AEHBAABJQHzCAAB8wElJAABBwH0AQAG9AEAAfQBBwQA
ASUB8wEABvMBAAHzASUkAAEHAfQBAAHwBAcB8AEAAfQBBwQAASUB8wEAAW8EJQFvAQAB8wElJAABBwH0
CAAB9AEHBAABJQHzCAAB8wElJAABBwH0AQAG8AEAAfQBBwQAASUB8wEABm8BAAHzASUkAAEHAfQBAAbw
AQAB9AEHBAABJQHzAQAGbwEAAfMBJSQAAQcB9AgAAfQBBwQAASUB8wgAAfMBJSQAAQcB9AEAAfAEBwHw
AQAB9AEHBAABJQHzAQABbwQlAW8BAAHzASUkAAEHAfQBAAb0AQAB9AEHBAABJQHzAQAG8wEAAfMBJSQA
AQcB9AgAAfQBBwQAASUB8wgAAfMBJSQAAQcK8AEHBAABJQpvASUkAAHyCvAB8gQAARoKbwEaYgABQgFN
AT4HAAE+AwABKAMAAUADAAEQAwABAQEAAQEFAAGAFwAD/wEABP8EAAHAAQMBwAEDBAABwAEDAcABAwQA
Ac8B8wHPAfMEAAHIARMByAETBAAByAETAcgBEwQAAc8B8wHPAfMEAAHIARMByAETBAAByAETAcgBEwQA
Ac8B8wHPAfMEAAHIARMByAETBAAByAETAcgBEwQAAc8B8wHPAfMEAAHAAQMBwAEDBAABwAEDAcABAwQA
BP8EAAs=
</value>
</data>
<metadata name="cmsDetail.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>735, 18</value>
</metadata>
<metadata name="tsFuncInfo.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>408, 18</value>
</metadata>
<metadata name="tsBaseInfo.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>521, 18</value>
</metadata>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>243</value>
</metadata>
</root>
\ No newline at end of file
namespace Tools.UI
{
partial class wXmlGenerator
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.panelHeader = new System.Windows.Forms.Panel();
this.lbLinkString = new System.Windows.Forms.Label();
this.btnConfig = new System.Windows.Forms.Button();
this.txtTableName = new System.Windows.Forms.TextBox();
this.labProduct = new System.Windows.Forms.Label();
this.btnGetColumns = new System.Windows.Forms.Button();
this.tabCtrSelf = new System.Windows.Forms.TabControl();
this.tabXmSetting = new System.Windows.Forms.TabPage();
this.dgvDetail = new System.Windows.Forms.DataGridView();
this.tabXmlText = new System.Windows.Forms.TabPage();
this.txtXml = new System.Windows.Forms.TextBox();
this.btnBuildXml = new System.Windows.Forms.Button();
this.panelFooter = new System.Windows.Forms.Panel();
this.Column1 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column2 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column3 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column4 = new System.Windows.Forms.DataGridViewCheckBoxColumn();
this.Column5 = new System.Windows.Forms.DataGridViewCheckBoxColumn();
this.Column6 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column7 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column8 = new System.Windows.Forms.DataGridViewCheckBoxColumn();
this.Column9 = new System.Windows.Forms.DataGridViewCheckBoxColumn();
this.Column10 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Column11 = new System.Windows.Forms.DataGridViewCheckBoxColumn();
this.Column12 = new System.Windows.Forms.DataGridViewCheckBoxColumn();
this.Column13 = new System.Windows.Forms.DataGridViewCheckBoxColumn();
this.panelHeader.SuspendLayout();
this.tabCtrSelf.SuspendLayout();
this.tabXmSetting.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.dgvDetail)).BeginInit();
this.tabXmlText.SuspendLayout();
this.panelFooter.SuspendLayout();
this.SuspendLayout();
//
// panelHeader
//
this.panelHeader.Controls.Add(this.lbLinkString);
this.panelHeader.Controls.Add(this.btnConfig);
this.panelHeader.Controls.Add(this.txtTableName);
this.panelHeader.Controls.Add(this.labProduct);
this.panelHeader.Controls.Add(this.btnGetColumns);
this.panelHeader.Dock = System.Windows.Forms.DockStyle.Top;
this.panelHeader.Location = new System.Drawing.Point(0, 0);
this.panelHeader.Name = "panelHeader";
this.panelHeader.Size = new System.Drawing.Size(800, 47);
this.panelHeader.TabIndex = 8;
//
// lbLinkString
//
this.lbLinkString.ForeColor = System.Drawing.Color.Green;
this.lbLinkString.Location = new System.Drawing.Point(613, 12);
this.lbLinkString.Name = "lbLinkString";
this.lbLinkString.Size = new System.Drawing.Size(174, 23);
this.lbLinkString.TabIndex = 356;
this.lbLinkString.Text = "请先配置数据库链接";
this.lbLinkString.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// btnConfig
//
this.btnConfig.Location = new System.Drawing.Point(518, 12);
this.btnConfig.Name = "btnConfig";
this.btnConfig.Size = new System.Drawing.Size(89, 23);
this.btnConfig.TabIndex = 355;
this.btnConfig.Text = "配置数据库";
this.btnConfig.UseVisualStyleBackColor = true;
//
// txtTableName
//
this.txtTableName.Location = new System.Drawing.Point(78, 14);
this.txtTableName.Name = "txtTableName";
this.txtTableName.Size = new System.Drawing.Size(192, 21);
this.txtTableName.TabIndex = 354;
//
// labProduct
//
this.labProduct.Location = new System.Drawing.Point(12, 14);
this.labProduct.Name = "labProduct";
this.labProduct.Size = new System.Drawing.Size(60, 18);
this.labProduct.TabIndex = 338;
this.labProduct.Text = "XML名称:";
this.labProduct.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// btnGetColumns
//
this.btnGetColumns.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btnGetColumns.ForeColor = System.Drawing.Color.Black;
this.btnGetColumns.Location = new System.Drawing.Point(323, 12);
this.btnGetColumns.Name = "btnGetColumns";
this.btnGetColumns.Size = new System.Drawing.Size(140, 23);
this.btnGetColumns.TabIndex = 6;
this.btnGetColumns.Text = "获取表的列配置信息";
this.btnGetColumns.UseVisualStyleBackColor = true;
//
// tabCtrSelf
//
this.tabCtrSelf.Controls.Add(this.tabXmSetting);
this.tabCtrSelf.Controls.Add(this.tabXmlText);
this.tabCtrSelf.Dock = System.Windows.Forms.DockStyle.Fill;
this.tabCtrSelf.Location = new System.Drawing.Point(0, 47);
this.tabCtrSelf.Name = "tabCtrSelf";
this.tabCtrSelf.SelectedIndex = 0;
this.tabCtrSelf.Size = new System.Drawing.Size(800, 421);
this.tabCtrSelf.TabIndex = 9;
//
// tabXmSetting
//
this.tabXmSetting.Controls.Add(this.dgvDetail);
this.tabXmSetting.Location = new System.Drawing.Point(4, 22);
this.tabXmSetting.Name = "tabXmSetting";
this.tabXmSetting.Size = new System.Drawing.Size(792, 395);
this.tabXmSetting.TabIndex = 0;
this.tabXmSetting.Text = "数据配置";
//
// dgvDetail
//
this.dgvDetail.BackgroundColor = System.Drawing.SystemColors.Window;
this.dgvDetail.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dgvDetail.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.Column1,
this.Column2,
this.Column3,
this.Column4,
this.Column5,
this.Column6,
this.Column7,
this.Column8,
this.Column9,
this.Column10,
this.Column11,
this.Column12,
this.Column13});
this.dgvDetail.Dock = System.Windows.Forms.DockStyle.Fill;
this.dgvDetail.GridColor = System.Drawing.SystemColors.AppWorkspace;
this.dgvDetail.Location = new System.Drawing.Point(0, 0);
this.dgvDetail.Name = "dgvDetail";
this.dgvDetail.RowTemplate.Height = 23;
this.dgvDetail.Size = new System.Drawing.Size(792, 395);
this.dgvDetail.TabIndex = 12;
//
// tabXmlText
//
this.tabXmlText.Controls.Add(this.txtXml);
this.tabXmlText.Location = new System.Drawing.Point(4, 22);
this.tabXmlText.Name = "tabXmlText";
this.tabXmlText.Size = new System.Drawing.Size(792, 395);
this.tabXmlText.TabIndex = 1;
this.tabXmlText.Text = "XML文本";
this.tabXmlText.UseVisualStyleBackColor = true;
//
// txtXml
//
this.txtXml.Dock = System.Windows.Forms.DockStyle.Fill;
this.txtXml.Location = new System.Drawing.Point(0, 0);
this.txtXml.MaxLength = 32767000;
this.txtXml.Multiline = true;
this.txtXml.Name = "txtXml";
this.txtXml.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
this.txtXml.Size = new System.Drawing.Size(792, 395);
this.txtXml.TabIndex = 0;
//
// btnBuildXml
//
this.btnBuildXml.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btnBuildXml.ForeColor = System.Drawing.Color.Black;
this.btnBuildXml.Location = new System.Drawing.Point(357, 9);
this.btnBuildXml.Name = "btnBuildXml";
this.btnBuildXml.Size = new System.Drawing.Size(100, 23);
this.btnBuildXml.TabIndex = 12;
this.btnBuildXml.Text = "生成XML文本";
this.btnBuildXml.UseVisualStyleBackColor = true;
//
// panelFooter
//
this.panelFooter.Controls.Add(this.btnBuildXml);
this.panelFooter.Dock = System.Windows.Forms.DockStyle.Bottom;
this.panelFooter.Location = new System.Drawing.Point(0, 468);
this.panelFooter.Name = "panelFooter";
this.panelFooter.Size = new System.Drawing.Size(800, 41);
this.panelFooter.TabIndex = 13;
//
// Column1
//
this.Column1.DataPropertyName = "Name";
this.Column1.HeaderText = "列名";
this.Column1.Name = "Column1";
//
// Column2
//
this.Column2.DataPropertyName = "Description";
this.Column2.HeaderText = "显示名称";
this.Column2.Name = "Column2";
//
// Column3
//
this.Column3.DataPropertyName = "DataType";
this.Column3.HeaderText = "数据类型";
this.Column3.Name = "Column3";
//
// Column4
//
this.Column4.DataPropertyName = "IsNull";
this.Column4.HeaderText = "是否为空";
this.Column4.Name = "Column4";
this.Column4.Resizable = System.Windows.Forms.DataGridViewTriState.True;
this.Column4.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic;
//
// Column5
//
this.Column5.DataPropertyName = "IsKey";
this.Column5.HeaderText = "是否主键";
this.Column5.Name = "Column5";
this.Column5.Resizable = System.Windows.Forms.DataGridViewTriState.True;
this.Column5.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic;
//
// Column6
//
this.Column6.DataPropertyName = "MaxLength";
this.Column6.HeaderText = "最大长度";
this.Column6.Name = "Column6";
//
// Column7
//
this.Column7.DataPropertyName = "ShowWidth";
this.Column7.HeaderText = "显示宽度";
this.Column7.Name = "Column7";
//
// Column8
//
this.Column8.DataPropertyName = "IsVisible";
this.Column8.HeaderText = "是否显示";
this.Column8.Name = "Column8";
this.Column8.Resizable = System.Windows.Forms.DataGridViewTriState.True;
this.Column8.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic;
//
// Column9
//
this.Column9.DataPropertyName = "IsEditHide";
this.Column9.HeaderText = "编辑可见";
this.Column9.Name = "Column9";
this.Column9.Resizable = System.Windows.Forms.DataGridViewTriState.True;
this.Column9.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic;
//
// Column10
//
this.Column10.DataPropertyName = "OrderIndex";
this.Column10.HeaderText = "排序号";
this.Column10.Name = "Column10";
//
// Column11
//
this.Column11.DataPropertyName = "CanEdit";
this.Column11.HeaderText = "是否编辑";
this.Column11.Name = "Column11";
this.Column11.Resizable = System.Windows.Forms.DataGridViewTriState.True;
this.Column11.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic;
//
// Column12
//
this.Column12.DataPropertyName = "CanSort";
this.Column12.HeaderText = "排序字段";
this.Column12.Name = "Column12";
this.Column12.Resizable = System.Windows.Forms.DataGridViewTriState.True;
this.Column12.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic;
//
// Column13
//
this.Column13.DataPropertyName = "SummaryItem";
this.Column13.HeaderText = "合计字段";
this.Column13.Name = "Column13";
this.Column13.Resizable = System.Windows.Forms.DataGridViewTriState.True;
this.Column13.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic;
//
// wXmlGenerator
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 509);
this.Controls.Add(this.tabCtrSelf);
this.Controls.Add(this.panelHeader);
this.Controls.Add(this.panelFooter);
this.Name = "wXmlGenerator";
this.Text = "wXmlGenerator";
this.Load += new System.EventHandler(this.wXmlGenerator_Load);
this.panelHeader.ResumeLayout(false);
this.panelHeader.PerformLayout();
this.tabCtrSelf.ResumeLayout(false);
this.tabXmSetting.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.dgvDetail)).EndInit();
this.tabXmlText.ResumeLayout(false);
this.tabXmlText.PerformLayout();
this.panelFooter.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Panel panelHeader;
private System.Windows.Forms.TextBox txtTableName;
private System.Windows.Forms.Label labProduct;
private System.Windows.Forms.Button btnGetColumns;
private System.Windows.Forms.TabControl tabCtrSelf;
private System.Windows.Forms.TabPage tabXmSetting;
private System.Windows.Forms.TabPage tabXmlText;
private System.Windows.Forms.TextBox txtXml;
private System.Windows.Forms.Button btnBuildXml;
private System.Windows.Forms.Panel panelFooter;
private System.Windows.Forms.DataGridView dgvDetail;
private System.Windows.Forms.Button btnConfig;
private System.Windows.Forms.Label lbLinkString;
private System.Windows.Forms.DataGridViewTextBoxColumn Column1;
private System.Windows.Forms.DataGridViewTextBoxColumn Column2;
private System.Windows.Forms.DataGridViewTextBoxColumn Column3;
private System.Windows.Forms.DataGridViewCheckBoxColumn Column4;
private System.Windows.Forms.DataGridViewCheckBoxColumn Column5;
private System.Windows.Forms.DataGridViewTextBoxColumn Column6;
private System.Windows.Forms.DataGridViewTextBoxColumn Column7;
private System.Windows.Forms.DataGridViewCheckBoxColumn Column8;
private System.Windows.Forms.DataGridViewCheckBoxColumn Column9;
private System.Windows.Forms.DataGridViewTextBoxColumn Column10;
private System.Windows.Forms.DataGridViewCheckBoxColumn Column11;
private System.Windows.Forms.DataGridViewCheckBoxColumn Column12;
private System.Windows.Forms.DataGridViewCheckBoxColumn Column13;
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
//
using Tools.MyCommon;
using Tools.MyUtils;
namespace Tools.UI
{
public partial class wXmlGenerator : wEditBasic
{
/// <summary>
/// 存放xml信息的表
/// </summary>
private DataSet _dsXmlSetting;
/// <summary>
/// 存放xml表名称
/// </summary>
private string _tableName => txtTableName.Text.Trim();
public wXmlGenerator()
{
InitializeComponent();
}
private void wXmlGenerator_Load(object sender, EventArgs e)
{
this.InitUI();
}
public override void InitUI()
{
base.InitUI();
//数据表格初始化
this.dgvDetail.AllowUserToAddRows = false;
this.dgvDetail.AutoGenerateColumns = false;
//添加按钮事件
this.btnConfig.Click += BtnConfig_Click;
this.btnGetColumns.Click += BtnGetColumns_Click; ;
this.btnBuildXml.Click += BtnBuildXml_Click;
}
/// <summary>
/// 按钮事件:配置数据库
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void BtnConfig_Click(object sender, EventArgs e)
{
var frm = new wDbSetting(this.lbLinkString);
if (frm.ShowDialog() == DialogResult.OK)
{
this.InitDBHelper(frm.LinkModel);
}
}
/// <summary>
/// 按钮事件:获取列信息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void BtnGetColumns_Click(object sender, EventArgs e)
{
if (this.CheckDbSetting())
return;
//根据表名获取对应的表结构
this._ds = this.GetTableSchema(this._tableName);
if (this._ds == null)
return;
//初始化配置信息表
this._dsXmlSetting = this.InitColumnInfo(this._ds);
//绑定数据源
this.dgvDetail.DataSource = this._dsXmlSetting.Tables[0].DefaultView;
}
/// <summary>
/// 按钮事件:生成MXL文本
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void BtnBuildXml_Click(object sender, EventArgs e)
{
if (this.CheckDbSetting())
return;
//生成Xml对象
var xml = this.GenXmlDocument();
//生成Xml文本
txtXml.Text = ConvertXmlToString(xml);
//选中<Xml文本>选项卡
tabCtrSelf.SelectedTab = tabXmlText;
}
/// <summary>
/// 获取表结构
/// </summary>
/// <param name="tableName"></param>
/// <returns></returns>
private DataSet GetTableSchema(string tableName)
{
DataSet result = null;
try
{
string sql = $"Select * From {tableName} p Where 1=2";
result = this._db.GetData(sql, tableName);
}
catch (Exception ex)
{
Utils.Tip($"xml名称:有误!: {ex.Message}");
}
return result;
}
/// <summary>
/// 初始化配置信息
/// </summary>
/// <param name="tableName"></param>
private DataSet InitColumnInfo(DataSet ds)
{
DataSet result = new DataSet();
#region 初始化XML配置表结构
result.Tables.Add(new DataTable()
{
Columns = {
{ "Name", typeof(string) },
{ "Description", typeof(string) },
{ "DataType", typeof(string) },
{ "IsNull", typeof(bool) },
{ "IsKey", typeof(bool) },
{ "MaxLength", typeof(int) },
{ "ShowWidth", typeof(int) },
{ "IsVisible", typeof(bool)},
{ "IsEditHide", typeof(bool)},
{ "OrderIndex", typeof(int)},
{ "CanEdit", typeof(bool)},
{ "CanSort", typeof(bool)},
{ "SummaryItem", typeof(bool)},
},
});
#endregion
//初始化列属性
ds.Tables[0].Columns.Cast<DataColumn>().ToList()
.ForEach(col => {
bool isKey = ds.Tables[0].PrimaryKey.Contains(col);
var dr = result.Tables[0].NewRow();
dr["Name"] = col.ColumnName;
dr["DataType"] = col.DataType.FullName;
dr["IsNull"] = col.AllowDBNull;
dr["IsKey"] = isKey;
dr["MaxLength"] = col.MaxLength < 0 ? 10 : col.MaxLength;
dr["ShowWidth"] = 100;
dr["IsVisible"] = !isKey;
dr["CanEdit"] = !isKey;
dr["SummaryItem"] = false; //是否合计
dr.EndEdit();
result.Tables[0].Rows.Add(dr);
});
return result;
}
/// <summary>
/// 将XmlDocument转化为string
/// </summary>
/// <param name="xmlDoc"></param>
/// <returns></returns>
public string ConvertXmlToString(XmlDocument xmlDoc)
{
string result = "";
using (MemoryStream ms = new MemoryStream())
{
//生成缩进格式
XmlTextWriter writer = new XmlTextWriter(ms, Encoding.UTF8);
writer.Formatting = Formatting.Indented; //缩进
xmlDoc.Save(writer);
//读取缩进后内容
StreamReader sr = new StreamReader(ms, Encoding.UTF8);
ms.Position = 0; //重置流位置
result = sr.ReadToEnd();
//关闭流对象
sr.Close();
writer.Close();
}
return result;
}
/// <summary>
/// 创建XML文本
/// </summary>
/// <param name="IsSaveToXml"></param>
private XmlDocument GenXmlDocument()
{
#region 生成XML配置文件
//创建xml文档对象
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.AppendChild(xmlDoc.CreateXmlDeclaration("1.0", "utf-8", ""));
//添加根节点
XmlNode root = xmlDoc.CreateElement("Entity");
xmlDoc.AppendChild(root);
//基本信息
this.AddChild(xmlDoc, root, "EntityTypeName", this._tableName); //实体表
this.AddChild(xmlDoc, root, "TableKeyName", "ID"); //数据库表
this.AddChild(xmlDoc, root, "TableName", this._tableName); //表名
this.AddChild(xmlDoc, root, "LinkFilterCtl", "U.WinCtl.Design.ucAutoDateFilter,U.WinCtl.DLL"); //查询
this.AddChild(xmlDoc, root, "FormEditConfigure", "U.WinClientDoc.EditCtlconfigureHelper,U.WinClientDoc.DL"); //配置窗体
this.AddChild(xmlDoc, root, "RefreshOnStringEmpty", "true"); //刷新
this.AddChild(xmlDoc, root, "DetailMerge", " "); //合并
this.AddChild(xmlDoc, root, "TableAlias", "a"); //查询别名
//图像浏览窗口必须配置的相关信息
var viewImgElement = xmlDoc.CreateElement("ViewImageList");
this.AddChild(xmlDoc, viewImgElement, "KeyFieldName", " ");
this.AddChild(xmlDoc, viewImgElement, "RemarkFieldName", " ");
this.AddChild(xmlDoc, viewImgElement, "RemarkFieldCaption", " ");
this.AddChild(xmlDoc, viewImgElement, "ImageFieldName", " ");
root.AppendChild(viewImgElement);
//网格编辑列需要配置的信息
this.AddChild(xmlDoc, root, "EditUI", " ");
//列信息配置
var columnsNode = xmlDoc.CreateElement("Columns");
foreach (DataRow row in this._dsXmlSetting.Tables[0].Rows)
{
XmlNode col = xmlDoc.CreateNode(XmlNodeType.Element, "Column", "");
foreach (DataColumn dc in this._dsXmlSetting.Tables[0].Columns)
{
object value = row[dc.ColumnName];
if (dc.ColumnName == "Columns_Id" || value.ToString() == "")
continue;
XmlAttribute attr = xmlDoc.CreateAttribute(dc.ColumnName);
attr.InnerText = dc.DataType.ToString() == "System.Boolean" ? value.ToString().ToLower() : value.ToString();
col.Attributes.Append(attr);
}
columnsNode.AppendChild(col);
}
root.AppendChild(columnsNode);
//配置通用增删改查SQL语句
var sqlsNode = xmlDoc.CreateElement("Sqls");
string strKey = _ds.Tables[0].Columns[0].ToString(); //首列一般主键列
string keyWhere = $" {strKey}=@{strKey} ";
var columnList = this._ds.Tables[0].Columns.Cast<DataColumn>().Select(c => c.ColumnName).ToList();
#region SelectObject
//SQL配置基本设置
XmlNode sqlNode = this.CreateSqlNode(xmlDoc, sqlsNode, "SelectObject");
//生成SQL
var str = $" <![CDATA[ Select a.{string.Join(", a.", columnList)} From {this._tableName} as a where {keyWhere}; ]]>";
this.AddSqlStringNode(xmlDoc, sqlNode, str);
//生成参数
this.AddParamNode(xmlDoc, sqlNode, strKey);
#endregion
#region AddObject
//SQL基本信息
sqlNode = this.CreateSqlNode(xmlDoc, sqlsNode, "AddObject");
//生成SQL
str = $" <![CDATA[ INSERT INTO {this._tableName}( {string.Join(", ", columnList)} ) VALUES( @{string.Join(", @", columnList)} ) ]]>";
this.AddSqlStringNode(xmlDoc, sqlNode, str);
//生成参数
foreach (DataColumn dc in _ds.Tables[0].Columns)
{
this.AddParamNode(xmlDoc, sqlNode, dc.ColumnName);
}
#endregion
#region UpdateObject
//SQL基本信息
sqlNode = this.CreateSqlNode(xmlDoc, sqlsNode, "UpdateObject");
//生成SQL
var pairlist = columnList.Select(s => $"{s}=@{s}").ToList();
str = $" <![CDATA[ UPDATE {this._tableName} SET {string.Join(", ", pairlist)} Where {keyWhere}; ]]>";
this.AddSqlStringNode(xmlDoc, sqlNode, str);
//生成参数
foreach (DataColumn dc in _ds.Tables[0].Columns)
{
this.AddParamNode(xmlDoc, sqlNode, dc.ColumnName);
}
#endregion
#region DeleteObject
//SQL基本信息
sqlNode = this.CreateSqlNode(xmlDoc, sqlsNode, "DeleteObject");
//生成DeleteObject语句
str = $"<![CDATA[ DELETE FROM {this._tableName} Where {keyWhere}; ]]>";
this.AddSqlStringNode(xmlDoc, sqlNode, str);
//生成参数
this.AddParamNode(xmlDoc, sqlNode, strKey);
#endregion
root.AppendChild(sqlsNode);
return xmlDoc;
#endregion
}
/// <summary>
/// XmlNode添加子节点
/// </summary>
/// <param name="xml"></param>
/// <param name="parent"></param>
/// <param name="name"></param>
/// <param name="InnerText"></param>
private void AddChild(XmlDocument xml, XmlNode parent, string name, string InnerText)
{
var child = xml.CreateElement(name);
child.InnerText = InnerText;
parent.AppendChild(child);
}
/// <summary>
/// 创建SQL节点
/// </summary>
/// <param name="xml"></param>
/// <param name="parent"></param>
/// <param name="value"></param>
private XmlNode CreateSqlNode(XmlDocument xml, XmlNode parent, string value)
{
//创建SQL节点
var node = xml.CreateNode(XmlNodeType.Element, "Sql", "");
//添加Name属性
var attr = xml.CreateAttribute("Name");
attr.Value = value;
node.Attributes.Prepend(attr);
//添加到父节点
parent.AppendChild(node);
return node;
}
/// <summary>
/// 添加String节点
/// </summary>
/// <param name="xml"></param>
/// <param name="parent"></param>
/// <param name="sqlString"></param>
private void AddSqlStringNode(XmlDocument xml, XmlNode parent, string sqlString)
{
//创建String节点
var node = xml.CreateNode(XmlNodeType.Element, "String", "");
node.InnerText = sqlString;
node.InnerXml = sqlString;
//添加到父节点
parent.AppendChild(node);
}
/// <summary>
/// 添加参数节点
/// </summary>
/// <param name="xml"></param>
/// <param name="parent"></param>
/// <param name="name"></param>
private void AddParamNode(XmlDocument xml, XmlNode parent, string name)
{
//创建参数节点
var node = xml.CreateNode(XmlNodeType.Element, "Param", "");
//设置Column属性
var attr = xml.CreateAttribute("Column");
attr.Value = name;
node.Attributes.Prepend(attr);
parent.AppendChild(node);
//设置Name属性
attr = xml.CreateAttribute("Name");
attr.Value = $"@{name}";
node.Attributes.Prepend(attr);
//绑定父节点
parent.AppendChild(node);
}
/// <summary>
/// 检查数据库配置
/// </summary>
/// <returns></returns>
public bool CheckDbSetting()
{
bool result = false;
if (this._db == null)
{
Utils.Tip("请先配置数据库链接!");
result = true;
}
return result;
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="Column1.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column2.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column3.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column4.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column5.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column6.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column7.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column8.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column9.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column10.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column11.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column12.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column13.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root>
\ No newline at end of file
......@@ -31,21 +31,24 @@ namespace Tools
this.CreateModule(typeof(UI.wAutoClass), "类生成工具"),
this.CreateModule(typeof(UI.wAuditDemo), "审批示例", "tr"),
this.CreateModule(typeof(UI.wImageSearch), "图片搜索", "tr"),
this.CreateModule(typeof(UI.wXmlGenerator), "XML生成器", "tr"),
this.CreateModule(typeof(UI.wModuleManager), "模块管理", "tr"),
this.CreateModule(typeof(UI.wLoginPwd), "登录密码", "tr"),
};
}
/// <summary>
/// 生成模块信息
/// </summary>
/// <param name="frm">窗体对象</param>
/// <param name="frmType">窗体对象</param>
/// <param name="text">显示名称</param>
/// <param name="tip">提示信息</param>
/// <param name="imgPath">图片路径</param>
/// <returns></returns>
private ModuleInfo CreateModule(Type frm, string text, string tip = "")
private ModuleInfo CreateModule(Type frmType, string text, string tip = "")
{
return new ModuleInfo {
FrmView = frm,
ViewFormType = frmType,
Text = text,
ToolTipText = tip,
};
......
......@@ -42,7 +42,7 @@ namespace Tools
Text = m.Text,
ToolTipText = m.ToolTipText,
ImageIndex = 1,
Tag = m.FrmView,
Tag = m.ViewFormType,
});
}
}
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/>
</startup>
</configuration>
using Dapper;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace test.DBO
{
/// <summary>
/// Dapper Dbo.
/// 更换不同数据库,只需修改 NewConn <see cref="NewConn"/> 以及少量代码 <see cref="GetDataSet"/> <see cref="GetDataTable"/>
/// </summary>
public class DbDapper : IDisposable
{
public static bool DEBUG_MODE = false;
private readonly string connectionString;
private System.Data.IDbConnection conn;
/// <summary>
/// 平台用、企业相关操作禁止使用。
/// </summary>
/// <param name="dbConnectionString"></param>
public DbDapper(string dbConnectionString)
{
connectionString = dbConnectionString;
}
public IDbConnection NewConn()
{
// return new NpgsqlConnection(connectionString);
return new SqlConnection(connectionString);
}
/// <summary>
/// 在委托里执行一堆事务
/// 委托成功执行会自动提交事件,失败会自动回滚.
/// 注意:不要在这个委托里调用 带 Async的异步方法,可能会造成问题:BeginExecuteNonQuery requires an open and available Connection. The connection's current state is open
/// </summary>
/// <param name="action"></param>
public void Trans(Action<IDbConnection, IDbTransaction> action)
{
using (var conn = NewConn())
{
conn.Open();
using (var trans = conn.BeginTransaction())
{
try
{
action(conn, trans);
trans.Commit();
}
catch (Exception)
{
trans.Rollback();
throw;
}
}
conn.Close();
}
}
public T ExecuteScalar<T>(string commandText, object paras = null)
{
using (var conn = NewConn())
{
return conn.ExecuteScalar<T>(commandText, paras, commandType: CommandType.Text);
}
}
public async Task<T> ExecuteScalarAsync<T>(string commandText, object paras = null)
{
using (var conn = NewConn())
{
return await conn.ExecuteScalarAsync<T>(commandText, paras, commandType: CommandType.Text);
}
}
public async Task<T> QueryFirstAsync<T>(string commandText, object paras = null)
{
using (var conn = NewConn())
{
return await conn.QueryFirstAsync<T>(commandText, paras, commandType: CommandType.Text);
}
}
public T QueryFirst<T>(string commandText, object paras = null)
{
using (var conn = NewConn())
{
return conn.QueryFirst<T>(commandText, paras, commandType: CommandType.Text);
}
}
public T QueryFirstOrDefault<T>(string commandText, object paras = null)
{
using (var conn = NewConn())
{
return conn.QueryFirstOrDefault<T>(commandText, paras, commandType: CommandType.Text);
}
}
public async Task<T> QueryFirstOrDefaultAsync<T>(string commandText, object paras = null)
{
using (var conn = NewConn())
{
return await conn.QueryFirstOrDefaultAsync<T>(commandText, paras, commandType: CommandType.Text);
}
}
public void Execute(string commandText, object paras = null)
{
using (var conn = NewConn())
{
conn.Execute(commandText, paras, commandType: CommandType.Text);
}
}
public async Task<int> ExecuteAsync(string commandText, object paras = null)
{
using (var conn = NewConn())
{
return await conn.ExecuteAsync(commandText, paras, commandType: CommandType.Text);
}
}
public async Task ExecuteAsyncByProc(string procName, object paras = null)
{
using (var conn = NewConn())
{
await conn.ExecuteAsync(procName, paras, commandType: CommandType.StoredProcedure);
}
}
public async Task<IEnumerable<T>> QueryAsync<T>(string commandText, object paras = null, CommandType commandType = CommandType.Text)
{
using (var conn = NewConn())
{
return await conn.QueryAsync<T>(commandText, paras, commandType: commandType);
}
}
public IEnumerable<T> Query<T>(string commandText, object paras = null)
{
using (var conn = NewConn())
{
return conn.Query<T>(commandText, paras, commandType: CommandType.Text);
}
}
public T ExecuteScalarByProc<T>(string procName, object paras = null)
{
using (var conn = NewConn())
{
return conn.ExecuteScalar<T>(procName, paras, commandType: CommandType.StoredProcedure);
}
}
public Task<T> QueryFirstAsyncByProc<T>(string procName, object paras = null)
{
using (var conn = NewConn())
{
return conn.QueryFirstAsync<T>(procName, paras, commandType: CommandType.StoredProcedure);
}
}
public Task ExecuteAsync<T>(string sql, object p)
{
throw new NotImplementedException();
}
public Task<IEnumerable<T>> QueryAsyncByProc<T>(string commandText, object paras = null)
{
using (var conn = NewConn())
{
return conn.QueryAsync<T>(commandText, paras, commandType: CommandType.StoredProcedure);
}
}
#region DataTable、DataSet
public DataTable GetTable(string commandText, object paras = null)
{
using (var conn = NewConn())
{
conn.Open();
using (var reader = conn.ExecuteReader(commandText, paras))
{
var dt = new DataTable();
while (reader.Read())
{
if (dt.Columns.Count == 0)
{
for (var i = 0; i < reader.FieldCount; i++)
{
dt.Columns.Add(reader.GetName(i), reader.GetFieldType(i));
}
}
var row = dt.Rows.Add();
for (var i = 0; i < reader.FieldCount; i++)
{
row[i] = reader.GetValue(i);
}
}
return dt;
}
}
}
public DataSet GetDataSet(string sql, object paras = null, bool isSp = false)
{
using (var conn = NewConn())
{
var ds = new DataSet();
using (var cmd = new SqlCommand(sql, (SqlConnection)conn))
{
if (isSp)
cmd.CommandType = CommandType.StoredProcedure;
if (paras != null)
{
var properties = paras.GetType().GetProperties();
foreach (var property in properties)
{
cmd.Parameters.AddWithValue("@" + property.Name, property.GetValue(paras, null));
}
}
using (var da = new SqlDataAdapter(cmd))
{
da.Fill(ds);
}
}
return ds;
}
}
/// <summary>
///
/// </summary>
/// <param name="sql"></param>
/// <param name="paras"></param>
/// <param name="isSp"></param>
/// <returns></returns>
public DataTable GetDataTable(string sql, object paras = null, bool isSp = false)
{
using (var conn = NewConn())
{
var dt = new DataTable();
using (var cmd = new SqlCommand(sql, (SqlConnection)conn))
{
if (isSp)
cmd.CommandType = CommandType.StoredProcedure;
if (paras != null)
{
var properties = paras.GetType().GetProperties();
foreach (var property in properties)
{
cmd.Parameters.AddWithValue("@" + property.Name, property.GetValue(paras, null));
}
}
using (var da = new SqlDataAdapter(cmd))
{
da.Fill(dt);
}
}
return dt;
}
}
#endregion
public void Dispose()
{
if (conn != null)
{
try
{
conn.Dispose();
}
catch
{
}
conn = null;
}
}
}
}

using FluentData;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;
using test.Extension;
namespace test.DBO
{
/// <summary>
/// 数据库操作类
/// 更换不同数据库,只需修改 NewConn <see cref="NewConn"/> 以及少量代码 <see cref="GetDataSet"/> <see cref="GetDataTable"/>
/// </summary>
public class DbFluentData
{
private string connectionString;
private readonly SqlServerProvider providerMssql = new SqlServerProvider();
public DbFluentData(string conn)
{
connectionString = conn;
}
public IDbContext NewContext()
{
return new DbContext().ConnectionString(connectionString, new SqlServerProvider(), (string)null);
}
#region Insert
/// <summary>
/// 插入元素
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="model"></param>
public void Insert<T>(T model)
{
using (IDbContext context = this.NewContext())
{
context.Insert<T>(typeof(T).Name, model).AutoMap(new Expression<Func<T, object>>[0]).Execute();
}
}
/// <summary>
/// 插入元素,并返回自增长的值.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="TKey"></typeparam>
/// <param name="model"></param>
/// <param name="keyExpression"></param>
/// <returns></returns>
public TKey Insert<T, TKey>(T model, Expression<Func<T, object>> keyExpression)
{
TKey result;
using (IDbContext context = this.NewContext())
{
result = context.Insert<T>(typeof(T).Name, model).AutoMap(new Expression<Func<T, object>>[]
{
keyExpression
}).ExecuteReturnLastId<TKey>(null);
}
return result;
}
public void Insert<T>(T model, params Expression<Func<T, object>>[] ignoreProperties)
{
using (IDbContext context = this.NewContext())
{
context.Insert<T>(typeof(T).Name, model).AutoMap(ignoreProperties).Execute();
}
}
/// <summary>
/// 往数据库里插入一个字典
/// </summary>
/// <param name="tableName"></param>
/// <param name="dict"></param>
public void Insert(string tableName, Dictionary<string, object> dict)
{
StringBuilder sb = new StringBuilder();
sb.Append(" INSERT INTO ");
sb.Append(tableName);
sb.Append(" ( ");
int i = 0;
foreach (KeyValuePair<string, object> o in dict)
{
if (i > 0)
{
sb.Append(",");
}
i++;
sb.Append(o.Key);
}
sb.Append(") values (");
i = 0;
foreach (KeyValuePair<string, object> o2 in dict)
{
if (i > 0)
{
sb.Append(",");
}
i++;
sb.Append("@").Append(o2.Key);
}
sb.Append(")");
using (IDbContext context = this.NewContext())
{
IDbCommand query = context.Sql(sb.ToString(), new object[0]);
foreach (KeyValuePair<string, object> o3 in dict)
{
query.Parameter(o3.Key, o3.Value, DataTypes.Object, ParameterDirection.Input, 0);
}
query.Execute();
}
}
/// <summary>
/// 往数据库里插入一下字典,并返回自增长键的值
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="tableName"></param>
/// <param name="dict"></param>
/// <returns></returns>
public T InsertAndReturnLastId<T>(string tableName, Dictionary<string, object> dict)
{
StringBuilder sb = new StringBuilder();
sb.Append(" INSERT INTO ");
sb.Append(tableName);
sb.Append(" ( ");
int i = 0;
foreach (KeyValuePair<string, object> o in dict)
{
if (i > 0)
{
sb.Append(",");
}
i++;
sb.Append(o.Key);
}
sb.Append(") values (");
i = 0;
foreach (KeyValuePair<string, object> o2 in dict)
{
if (i > 0)
{
sb.Append(",");
}
i++;
sb.Append("@").Append(o2.Key);
}
sb.Append(")");
T result;
using (IDbContext context = this.NewContext())
{
IDbCommand query = context.Sql(sb.ToString(), new object[0]);
foreach (KeyValuePair<string, object> o3 in dict)
{
query.Parameter(o3.Key, o3.Value, DataTypes.Object, ParameterDirection.Input, 0);
}
result = query.ExecuteReturnLastId<T>(null);
}
return result;
}
#endregion
#region Delete
public void DeleteAll<T>()
{
using (IDbContext ctx = this.NewContext())
{
ctx.Sql("delete from " + typeof(T).Name, new object[0]).Execute();
}
}
public void Delete<T>(string keyField, object value)
{
using (IDbContext ctx = this.NewContext())
{
ctx.Sql(string.Format("delete from {0} where {1}=@id", typeof(T).Name, keyField), new object[0]).Parameter("id", value, DataTypes.Object, ParameterDirection.Input, 0).Execute();
}
}
public void Delete<T>(Expression<Func<T, bool>> where)
{
using (IDbContext ctx = this.NewContext())
{
ExpressionExtension.BinaryExpressionInfo bi = where.GetBinaryExpressionInfo();
string keyField = bi.LeftName;
object value = bi.GetRightValue();
ctx.Sql(string.Format("delete from {0} where {1}=@id", typeof(T).Name, keyField), new object[0]).Parameter("id", value, DataTypes.Object, ParameterDirection.Input, 0).Execute();
}
}
#endregion
#region Update
/// <summary>
/// 数据字典内容,更新数据
/// </summary>
/// <param name="tableName"></param>
/// <param name="where"></param>
/// <param name="dict"></param>
public void Update(string tableName, string where, Dictionary<string, object> dict)
{
StringBuilder sb = new StringBuilder();
sb.Append(" UPDATE ");
sb.Append(tableName);
sb.Append(" SET ");
int i = 0;
foreach (KeyValuePair<string, object> o in dict)
{
if (i > 0)
{
sb.Append(",");
}
i++;
sb.Append(o.Key).Append("=@").Append(o.Key);
}
if (!string.IsNullOrEmpty(where))
{
sb.Append(" WHERE ").Append(where);
}
using (IDbContext context = this.NewContext())
{
IDbCommand query = context.Sql(sb.ToString(), new object[0]);
foreach (KeyValuePair<string, object> o2 in dict)
{
query.Parameter(o2.Key, o2.Value, DataTypes.Object, ParameterDirection.Input, 0);
}
query.Execute();
}
}
public void Update(string sql, Dictionary<string, object> dict)
{
using (IDbContext context = this.NewContext())
{
IDbCommand query = context.Sql(sql, new object[0]);
foreach (KeyValuePair<string, object> o2 in dict)
{
query.Parameter(o2.Key, o2.Value, DataTypes.Object, ParameterDirection.Input, 0);
}
query.Execute();
}
}
public void Update<T>(T model, Expression<Func<T, object>> where, params Expression<Func<T, object>>[] ignoreProperties)
{
using (IDbContext context = this.NewContext())
{
context.Update<T>(typeof(T).Name, model).AutoMap(new Expression<Func<T, object>>[]
{
where
}).Where(where, DataTypes.Object, 0).Execute();
}
}
#endregion
#region Select
public T SelectOne<T>(Expression<Func<T, bool>> where)
{
T result;
using (IDbContext ctx = this.NewContext())
{
ExpressionExtension.BinaryExpressionInfo bi = where.GetBinaryExpressionInfo();
string keyField = bi.LeftName;
object value = bi.GetRightValue();
result = ctx.Sql(string.Format("select * from {0} where {1}=@id", typeof(T).Name, keyField), new object[0]).Parameter("id", value, DataTypes.Object, ParameterDirection.Input, 0).QuerySingle<T>(null);
}
return result;
}
public List<T> SelectAll<T>()
{
List<T> result;
using (IDbContext context = this.NewContext())
{
result = context.SelectAll<T>();
}
return result;
}
public List<T> SelectAll<T>(params string[] fields)
{
if (fields == null || fields.Length == 0)
{
throw new ArgumentNullException("fields");
}
string fieldsString = fields.JoinString(",");
List<T> result;
using (IDbContext ctx = this.NewContext())
{
result = ctx.Sql(string.Format("select {0} from {1}", fieldsString, typeof(T).Name), new object[0]).QueryMany<T>(null);
}
return result;
}
/// <summary>
/// 执行一个SQL,返回多行
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sql"></param>
/// <param name="paras"></param>
/// <returns></returns>
public List<T> SelectMany<T>(string sql, params FluentDbParameter[] paras)
{
List<T> result;
using (IDbContext ctx = this.NewContext())
{
FluentData.IDbCommand query = ctx.Sql(sql, new object[0]);
if (paras != null)
{
for (int i = 0; i < paras.Length; i++)
{
FluentDbParameter para = paras[i];
query.Parameter(para.Key, para.Value, DataTypes.Object, FluentData.ParameterDirection.Input, 0);
}
}
result = query.QueryMany<T>(null);
}
return result;
}
#endregion
#region Exec
/// <summary>
/// 执行一个SQL,没有返回任何数据.
/// </summary>
/// <param name="sql"></param>
/// <param name="parameters"></param>
public void ExecuteNoQuery(string sql, params object[] parameters)
{
using (IDbContext context = this.NewContext())
{
context.Sql(sql, parameters).Execute();
}
}
public void Execute(string sql, Dictionary<string, object> dict)
{
using (IDbContext context = this.NewContext())
{
IDbCommand query = context.Sql(sql, new object[0]);
foreach (KeyValuePair<string, object> o2 in dict)
{
query.Parameter(o2.Key, o2.Value, DataTypes.Object, ParameterDirection.Input, 0);
}
query.Execute();
}
}
public void Execute(string sql, IEnumerable<Dictionary<string, object>> keyValuePairs)
{
using (IDbContext context = this.NewContext().UseTransaction(true))
{
foreach (var dict in keyValuePairs)
{
IDbCommand query = context.Sql(sql, new object[0]);
foreach (KeyValuePair<string, object> o2 in dict)
{
query.Parameter(o2.Key, o2.Value, DataTypes.Object, ParameterDirection.Input, 0);
}
query.Execute();
}
}
}
#endregion
}
public static class IDbContextExtension
{
/// <summary>
/// 自动编辑 select count 语句,并返回结果
/// </summary>
/// <param name="db"></param>
/// <param name="tableName"></param>
/// <param name="whereCondtion">WHERE后面的语句,各参数以p开头,0开始的命名规则.例 " UserID=@p0 and Password=@p1"</param>
/// <param name="paras"></param>
/// <returns></returns>
public static int Count(this IDbContext db, string tableName, string whereCondtion = null, params object[] paras)
{
StringBuilder sql = new StringBuilder();
sql.Append("select count(*) from ").Append(tableName);
if (whereCondtion != null)
{
sql.Append(" WHERE ").Append(whereCondtion);
}
IDbCommand cmd = db.Sql(sql.ToString(), new object[0]);
if (paras != null)
{
for (int i = 0; i < paras.Length; i++)
{
cmd = cmd.Parameter("p" + i, paras[i], DataTypes.Object, ParameterDirection.Input, 0);
}
}
return cmd.QuerySingle<int>(null);
}
public static SelectOneBuilder<T> SelectOne<T>(this IDbContext context)
{
return new SelectOneBuilder<T>(context);
}
/// <summary>
/// 根据条件,求符合条件的记录是否存在.类似本类中的 Count扩展方法
/// </summary>
/// <param name="db"></param>
/// <param name="tableName"></param>
/// <param name="whereCondtion"></param>
/// <param name="paras"></param>
/// <returns></returns>
public static bool Exists(this IDbContext db, string tableName, string whereCondtion = null, params object[] paras)
{
StringBuilder sql = new StringBuilder();
sql.Append("if exists (select * from ").Append(tableName);
if (whereCondtion != null)
{
sql.Append(" WHERE ").Append(whereCondtion);
}
sql.Append(" ) select 1 else select 0");
IDbCommand cmd = db.Sql(sql.ToString(), new object[0]);
if (paras != null)
{
for (int i = 0; i < paras.Length; i++)
{
cmd = cmd.Parameter("p" + i, paras[i], DataTypes.Object, ParameterDirection.Input, 0);
}
}
return cmd.QuerySingle<int>(null) > 0;
}
public static List<T> SelectAll<T>(this IDbContext db)
{
return db.Sql("select * from " + typeof(T).Name, new object[0]).QueryMany<T>(null);
}
}
public class SelectOneBuilder<T>
{
private readonly IDbContext context;
private readonly StringBuilder sb = new StringBuilder();
private readonly Dictionary<string, object> parameters = new Dictionary<string, object>();
public SelectOneBuilder(IDbContext context)
{
this.context = context;
this.sb.Append("SELECT * FROM ").Append(typeof(T).Name).Append(" WHERE 1=1 ");
}
public SelectOneBuilder<T> Where(string columnName, object value)
{
this.sb.Append(" AND ").Append(columnName).Append(" = @").Append(columnName);
this.parameters[columnName] = value;
return this;
}
public SelectOneBuilder<T> Where(Expression<Func<T, bool>> exp)
{
ExpressionExtension.BinaryExpressionInfo expInfo = exp.GetBinaryExpressionInfo();
string columnName = expInfo.LeftName;
object value = expInfo.GetRightValue();
this.sb.Append(" AND ");
ExpressionType nodeType = expInfo.Body.NodeType;
switch (nodeType)
{
case ExpressionType.Equal:
this.sb.AppendFormat("{0} = @{0}", columnName);
goto IL_E5;
case ExpressionType.ExclusiveOr:
case ExpressionType.Invoke:
case ExpressionType.Lambda:
case ExpressionType.LeftShift:
break;
case ExpressionType.GreaterThan:
this.sb.AppendFormat("{0} > @{0}", columnName);
goto IL_E5;
case ExpressionType.GreaterThanOrEqual:
this.sb.AppendFormat("{0} >= @{0}", columnName);
goto IL_E5;
case ExpressionType.LessThan:
this.sb.AppendFormat("{0} < @{0}", columnName);
goto IL_E5;
case ExpressionType.LessThanOrEqual:
this.sb.AppendFormat("{0} <= @{0}", columnName);
goto IL_E5;
default:
if (nodeType == ExpressionType.NotEqual)
{
this.sb.AppendFormat("{0} != @{0}", columnName);
goto IL_E5;
}
break;
}
throw new NotImplementedException();
IL_E5:
this.parameters[columnName] = value;
return this;
}
public T Execute()
{
string sql = this.sb.ToString();
IDbCommand cmd = this.context.Sql(sql, new object[0]);
foreach (KeyValuePair<string, object> p in this.parameters)
{
cmd.Parameter(p.Key, p.Value, DataTypes.Object, ParameterDirection.Input, 0);
}
return cmd.QuerySingle<T>(null);
}
}
public struct FluentDbParameter
{
public string Key;
public object Value;
public FluentDbParameter(string k, object v)
{
this.Key = k;
this.Value = v;
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace test.DBO
{
/// <summary>
/// The SqlHelper class is intended to encapsulate high performance, scalable best practices for
/// common uses of SqlClient.
/// </summary>
public sealed class DbSqlHelper
{
#region private utility methods & constructors
private const int TIMEOUT = 1000 * 60 * 10; //表示无限制等待。
//Since this class provides only static methods, make the default constructor private to prevent
//instances from being created with "new SqlHelper()".
private DbSqlHelper() { }
/// <summary>
/// This method is used to attach array of SqlParameters to a SqlCommand.
///
/// This method will assign a value of DbNull to any parameter with a direction of
/// InputOutput and a value of null.
///
/// This behavior will prevent default values from being used, but
/// this will be the less common case than an intended pure output parameter (derived as InputOutput)
/// where the user provided no input value.
/// </summary>
/// <param name="command">The command to which the parameters will be added</param>
/// <param name="commandParameters">an array of SqlParameters tho be added to command</param>
private static void AttachParameters(SqlCommand command, SqlParameter[] commandParameters)
{
foreach (SqlParameter p in commandParameters)
{
//check for derived output value with no value assigned
if ((p.Direction == ParameterDirection.InputOutput) && (p.Value == null))
{
p.Value = DBNull.Value;
}
command.Parameters.Add(p);
}
}
/// <summary>
/// This method assigns an array of values to an array of SqlParameters.
/// </summary>
/// <param name="commandParameters">array of SqlParameters to be assigned values</param>
/// <param name="parameterValues">array of objects holding the values to be assigned</param>
private static void AssignParameterValues(SqlParameter[] commandParameters, object[] parameterValues)
{
if ((commandParameters == null) || (parameterValues == null))
{
//do nothing if we get no data
return;
}
// we must have the same number of values as we pave parameters to put them in
if (commandParameters.Length != parameterValues.Length)
{
throw new ArgumentException("Parameter count does not match Parameter Value count.");
}
//iterate through the SqlParameters, assigning the values from the corresponding position in the
//value array
for (int i = 0, j = commandParameters.Length; i < j; i++)
{
commandParameters[i].Value = parameterValues[i];
}
}
/// <summary>
/// This method opens (if necessary) and assigns a connection, transaction, command type and parameters
/// to the provided command.
/// </summary>
/// <param name="command">the SqlCommand to be prepared</param>
/// <param name="connection">a valid SqlConnection, on which to execute this command</param>
/// <param name="transaction">a valid SqlTransaction, or 'null'</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <param name="commandParameters">an array of SqlParameters to be associated with the command or 'null' if no parameters are required</param>
private static void PrepareCommand(SqlCommand command, SqlConnection connection, SqlTransaction transaction, CommandType commandType, string commandText, SqlParameter[] commandParameters)
{
//if the provided connection is not open, we will open it
if (connection.State != ConnectionState.Open)
{
connection.Open();
}
//associate the connection with the command
command.Connection = connection;
//set the command text (stored procedure name or SQL statement)
command.CommandText = commandText;
//if we were provided a transaction, assign it.
if (transaction != null)
{
command.Transaction = transaction;
}
//set the command type
command.CommandType = commandType;
//attach the command parameters if they are provided
if (commandParameters != null)
{
AttachParameters(command, commandParameters);
}
return;
}
#endregion private utility methods & constructors
/// <summary>
/// 获取数据连接字符窜。
/// </summary>
/// <returns></returns>
#region ExecuteNonQuery
/// <summary>
/// Execute a SqlCommand (that returns no resultset and takes no parameters) against the database specified in
/// the connection string.
/// </summary>
/// <remarks>
/// e.g.:
/// int result = ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders");
/// </remarks>
/// <param name="connectionString">a valid connection string for a SqlConnection</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <returns>an int representing the number of rows affected by the command</returns>
public static int ExecuteNonQuery(string connectionString, CommandType commandType, string commandText)
{
//pass through the call providing null for the set of SqlParameters
return ExecuteNonQuery(connectionString, commandType, commandText, (SqlParameter[])null);
}
/// <summary>
/// Execute a SqlCommand (that returns no resultset) against the database specified in the connection string
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// int result = ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="connectionString">a valid connection string for a SqlConnection</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <param name="commandParameters">an array of SqlParamters used to execute the command</param>
/// <returns>an int representing the number of rows affected by the command</returns>
public static int ExecuteNonQuery(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
{
//create & open a SqlConnection, and dispose of it after we are done.
using (SqlConnection cn = new SqlConnection(connectionString))
{
cn.Open();
//call the overload that takes a connection in place of the connection string
return ExecuteNonQuery(cn, commandType, commandText, commandParameters);
}
}
/// <summary>
/// Execute a stored procedure via a SqlCommand (that returns no resultset) against the database specified in
/// the connection string using the provided parameter values. This method will query the database to discover the parameters for the
/// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
/// </summary>
/// <remarks>
/// This method provides no access to output parameters or the stored procedure's return value parameter.
///
/// e.g.:
/// int result = ExecuteNonQuery(connString, "PublishOrders", 24, 36);
/// </remarks>
/// <param name="connectionString">a valid connection string for a SqlConnection</param>
/// <param name="spName">the name of the stored prcedure</param>
/// <param name="parameterValues">an array of objects to be assigned as the input values of the stored procedure</param>
/// <returns>an int representing the number of rows affected by the command</returns>
public static int ExecuteNonQuery(string connectionString, string spName, params object[] parameterValues)
{
//if we receive parameter values, we need to figure out where they go
if ((parameterValues != null) && (parameterValues.Length > 0))
{
//pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
//assign the provided values to these parameters based on parameter order
AssignParameterValues(commandParameters, parameterValues);
//call the overload that takes an array of SqlParameters
return ExecuteNonQuery(connectionString, CommandType.StoredProcedure, spName, commandParameters);
}
//otherwise we can just call the SP without params
else
{
return ExecuteNonQuery(connectionString, CommandType.StoredProcedure, spName);
}
}
/// <summary>
/// Execute a SqlCommand (that returns no resultset and takes no parameters) against the provided SqlConnection.
/// </summary>
/// <remarks>
/// e.g.:
/// int result = ExecuteNonQuery(conn, CommandType.StoredProcedure, "PublishOrders");
/// </remarks>
/// <param name="connection">a valid SqlConnection</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <returns>an int representing the number of rows affected by the command</returns>
public static int ExecuteNonQuery(SqlConnection connection, CommandType commandType, string commandText)
{
//pass through the call providing null for the set of SqlParameters
return ExecuteNonQuery(connection, commandType, commandText, (SqlParameter[])null);
}
/// <summary>
/// Execute a SqlCommand (that returns no resultset) against the specified SqlConnection
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// int result = ExecuteNonQuery(conn, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="connection">a valid SqlConnection</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <param name="commandParameters">an array of SqlParamters used to execute the command</param>
/// <returns>an int representing the number of rows affected by the command</returns>
public static int ExecuteNonQuery(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
{
//create a command and prepare it for execution
SqlCommand cmd = new SqlCommand();
cmd.CommandTimeout = TIMEOUT; //add by steven
PrepareCommand(cmd, connection, (SqlTransaction)null, commandType, commandText, commandParameters);
//finally, execute the command.
int retval = cmd.ExecuteNonQuery();
// detach the SqlParameters from the command object, so they can be used again.
cmd.Parameters.Clear();
return retval;
}
/// <summary>
/// Execute a stored procedure via a SqlCommand (that returns no resultset) against the specified SqlConnection
/// using the provided parameter values. This method will query the database to discover the parameters for the
/// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
/// </summary>
/// <remarks>
/// This method provides no access to output parameters or the stored procedure's return value parameter.
///
/// e.g.:
/// int result = ExecuteNonQuery(conn, "PublishOrders", 24, 36);
/// </remarks>
/// <param name="connection">a valid SqlConnection</param>
/// <param name="spName">the name of the stored procedure</param>
/// <param name="parameterValues">an array of objects to be assigned as the input values of the stored procedure</param>
/// <returns>an int representing the number of rows affected by the command</returns>
public static int ExecuteNonQuery(SqlConnection connection, string spName, params object[] parameterValues)
{
//if we receive parameter values, we need to figure out where they go
if ((parameterValues != null) && (parameterValues.Length > 0))
{
//pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection.ConnectionString, spName);
//assign the provided values to these parameters based on parameter order
AssignParameterValues(commandParameters, parameterValues);
//call the overload that takes an array of SqlParameters
return ExecuteNonQuery(connection, CommandType.StoredProcedure, spName, commandParameters);
}
//otherwise we can just call the SP without params
else
{
return ExecuteNonQuery(connection, CommandType.StoredProcedure, spName);
}
}
/// <summary>
/// Execute a SqlCommand (that returns no resultset and takes no parameters) against the provided SqlTransaction.
/// </summary>
/// <remarks>
/// e.g.:
/// int result = ExecuteNonQuery(trans, CommandType.StoredProcedure, "PublishOrders");
/// </remarks>
/// <param name="transaction">a valid SqlTransaction</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <returns>an int representing the number of rows affected by the command</returns>
public static int ExecuteNonQuery(SqlTransaction transaction, CommandType commandType, string commandText)
{
//pass through the call providing null for the set of SqlParameters
return ExecuteNonQuery(transaction, commandType, commandText, (SqlParameter[])null);
}
/// <summary>
/// Execute a SqlCommand (that returns no resultset) against the specified SqlTransaction
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// int result = ExecuteNonQuery(trans, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="transaction">a valid SqlTransaction</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <param name="commandParameters">an array of SqlParamters used to execute the command</param>
/// <returns>an int representing the number of rows affected by the command</returns>
public static int ExecuteNonQuery(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
{
//create a command and prepare it for execution
SqlCommand cmd = new SqlCommand();
cmd.CommandTimeout = TIMEOUT; //add by steven
PrepareCommand(cmd, transaction.Connection, transaction, commandType, commandText, commandParameters);
//finally, execute the command.
int retval = cmd.ExecuteNonQuery();
// detach the SqlParameters from the command object, so they can be used again.
cmd.Parameters.Clear();
return retval;
}
/// <summary>
/// Execute a stored procedure via a SqlCommand (that returns no resultset) against the specified
/// SqlTransaction using the provided parameter values. This method will query the database to discover the parameters for the
/// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
/// </summary>
/// <remarks>
/// This method provides no access to output parameters or the stored procedure's return value parameter.
///
/// e.g.:
/// int result = ExecuteNonQuery(conn, trans, "PublishOrders", 24, 36);
/// </remarks>
/// <param name="transaction">a valid SqlTransaction</param>
/// <param name="spName">the name of the stored procedure</param>
/// <param name="parameterValues">an array of objects to be assigned as the input values of the stored procedure</param>
/// <returns>an int representing the number of rows affected by the command</returns>
public static int ExecuteNonQuery(SqlTransaction transaction, string spName, params object[] parameterValues)
{
//if we receive parameter values, we need to figure out where they go
if ((parameterValues != null) && (parameterValues.Length > 0))
{
//pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection.ConnectionString, spName);
//assign the provided values to these parameters based on parameter order
AssignParameterValues(commandParameters, parameterValues);
//call the overload that takes an array of SqlParameters
return ExecuteNonQuery(transaction, CommandType.StoredProcedure, spName, commandParameters);
}
//otherwise we can just call the SP without params
else
{
return ExecuteNonQuery(transaction, CommandType.StoredProcedure, spName);
}
}
#endregion ExecuteNonQuery
#region ExecuteDataSet
/// <summary>
/// Execute a SqlCommand (that returns a resultset and takes no parameters) against the database specified in
/// the connection string.
/// </summary>
/// <remarks>
/// e.g.:
/// DataSet ds = ExecuteDataset(connString, CommandType.StoredProcedure, "GetOrders");
/// </remarks>
/// <param name="connectionString">a valid connection string for a SqlConnection</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <returns>a dataset containing the resultset generated by the command</returns>
public static DataSet ExecuteDataset(string connectionString, CommandType commandType, string commandText)
{
//pass through the call providing null for the set of SqlParameters
return ExecuteDataset(connectionString, commandType, commandText, (SqlParameter[])null);
}
/// <summary>
/// Execute a SqlCommand (that returns a resultset) against the database specified in the connection string
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// DataSet ds = ExecuteDataset(connString, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="connectionString">a valid connection string for a SqlConnection</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <param name="commandParameters">an array of SqlParamters used to execute the command</param>
/// <returns>a dataset containing the resultset generated by the command</returns>
public static DataSet ExecuteDataset(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
{
//create & open a SqlConnection, and dispose of it after we are done.
using (SqlConnection cn = new SqlConnection(connectionString))
{
cn.Open();
//call the overload that takes a connection in place of the connection string
return ExecuteDataset(cn, commandType, commandText, commandParameters);
}
}
/// <summary>
/// Execute a stored procedure via a SqlCommand (that returns a resultset) against the database specified in
/// the connection string using the provided parameter values. This method will query the database to discover the parameters for the
/// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
/// </summary>
/// <remarks>
/// This method provides no access to output parameters or the stored procedure's return value parameter.
///
/// e.g.:
/// DataSet ds = ExecuteDataset(connString, "GetOrders", 24, 36);
/// </remarks>
/// <param name="connectionString">a valid connection string for a SqlConnection</param>
/// <param name="spName">the name of the stored procedure</param>
/// <param name="parameterValues">an array of objects to be assigned as the input values of the stored procedure</param>
/// <returns>a dataset containing the resultset generated by the command</returns>
public static DataSet ExecuteDataset(string connectionString, string spName, params object[] parameterValues)
{
//if we receive parameter values, we need to figure out where they go
if ((parameterValues != null) && (parameterValues.Length > 0))
{
//pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
//assign the provided values to these parameters based on parameter order
AssignParameterValues(commandParameters, parameterValues);
//call the overload that takes an array of SqlParameters
return ExecuteDataset(connectionString, CommandType.StoredProcedure, spName, commandParameters);
}
//otherwise we can just call the SP without params
else
{
return ExecuteDataset(connectionString, CommandType.StoredProcedure, spName);
}
}
/// <summary>
/// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlConnection.
/// </summary>
/// <remarks>
/// e.g.:
/// DataSet ds = ExecuteDataset(conn, CommandType.StoredProcedure, "GetOrders");
/// </remarks>
/// <param name="connection">a valid SqlConnection</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <returns>a dataset containing the resultset generated by the command</returns>
public static DataSet ExecuteDataset(SqlConnection connection, CommandType commandType, string commandText)
{
//pass through the call providing null for the set of SqlParameters
return ExecuteDataset(connection, commandType, commandText, (SqlParameter[])null);
}
/// <summary>
/// Execute a SqlCommand (that returns a resultset) against the specified SqlConnection
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// DataSet ds = ExecuteDataset(conn, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="connection">a valid SqlConnection</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <param name="commandParameters">an array of SqlParamters used to execute the command</param>
/// <returns>a dataset containing the resultset generated by the command</returns>
public static DataSet ExecuteDataset(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
{
//create a command and prepare it for execution
SqlCommand cmd = new SqlCommand();
PrepareCommand(cmd, connection, (SqlTransaction)null, commandType, commandText, commandParameters);
//create the DataAdapter & DataSet
SqlDataAdapter da = new SqlDataAdapter(cmd);
//让命令一直执行,直到用户取消它
da.SelectCommand.CommandTimeout = TIMEOUT;
DataSet ds = new DataSet();
//fill the DataSet using default values for DataTable names, etc.
da.Fill(ds);
// detach the SqlParameters from the command object, so they can be used again.
cmd.Parameters.Clear();
//return the dataset
return ds;
}
/// <summary>
/// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlConnection
/// using the provided parameter values. This method will query the database to discover the parameters for the
/// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
/// </summary>
/// <remarks>
/// This method provides no access to output parameters or the stored procedure's return value parameter.
///
/// e.g.:
/// DataSet ds = ExecuteDataset(conn, "GetOrders", 24, 36);
/// </remarks>
/// <param name="connection">a valid SqlConnection</param>
/// <param name="spName">the name of the stored procedure</param>
/// <param name="parameterValues">an array of objects to be assigned as the input values of the stored procedure</param>
/// <returns>a dataset containing the resultset generated by the command</returns>
public static DataSet ExecuteDataset(SqlConnection connection, string spName, params object[] parameterValues)
{
//if we receive parameter values, we need to figure out where they go
if ((parameterValues != null) && (parameterValues.Length > 0))
{
//pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection.ConnectionString, spName);
//assign the provided values to these parameters based on parameter order
AssignParameterValues(commandParameters, parameterValues);
//call the overload that takes an array of SqlParameters
return ExecuteDataset(connection, CommandType.StoredProcedure, spName, commandParameters);
}
//otherwise we can just call the SP without params
else
{
return ExecuteDataset(connection, CommandType.StoredProcedure, spName);
}
}
/// <summary>
/// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlTransaction.
/// </summary>
/// <remarks>
/// e.g.:
/// DataSet ds = ExecuteDataset(trans, CommandType.StoredProcedure, "GetOrders");
/// </remarks>
/// <param name="transaction">a valid SqlTransaction</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <returns>a dataset containing the resultset generated by the command</returns>
public static DataSet ExecuteDataset(SqlTransaction transaction, CommandType commandType, string commandText)
{
//pass through the call providing null for the set of SqlParameters
return ExecuteDataset(transaction, commandType, commandText, (SqlParameter[])null);
}
/// <summary>
/// Execute a SqlCommand (that returns a resultset) against the specified SqlTransaction
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// DataSet ds = ExecuteDataset(trans, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="transaction">a valid SqlTransaction</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <param name="commandParameters">an array of SqlParamters used to execute the command</param>
/// <returns>a dataset containing the resultset generated by the command</returns>
public static DataSet ExecuteDataset(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
{
//create a command and prepare it for execution
SqlCommand cmd = new SqlCommand();
PrepareCommand(cmd, transaction.Connection, transaction, commandType, commandText, commandParameters);
//create the DataAdapter & DataSet
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
//fill the DataSet using default values for DataTable names, etc.
da.Fill(ds);
// detach the SqlParameters from the command object, so they can be used again.
cmd.Parameters.Clear();
//return the dataset
return ds;
}
/// <summary>
/// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified
/// SqlTransaction using the provided parameter values. This method will query the database to discover the parameters for the
/// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
/// </summary>
/// <remarks>
/// This method provides no access to output parameters or the stored procedure's return value parameter.
///
/// e.g.:
/// DataSet ds = ExecuteDataset(trans, "GetOrders", 24, 36);
/// </remarks>
/// <param name="transaction">a valid SqlTransaction</param>
/// <param name="spName">the name of the stored procedure</param>
/// <param name="parameterValues">an array of objects to be assigned as the input values of the stored procedure</param>
/// <returns>a dataset containing the resultset generated by the command</returns>
public static DataSet ExecuteDataset(SqlTransaction transaction, string spName, params object[] parameterValues)
{
//if we receive parameter values, we need to figure out where they go
if ((parameterValues != null) && (parameterValues.Length > 0))
{
//pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection.ConnectionString, spName);
//assign the provided values to these parameters based on parameter order
AssignParameterValues(commandParameters, parameterValues);
//call the overload that takes an array of SqlParameters
return ExecuteDataset(transaction, CommandType.StoredProcedure, spName, commandParameters);
}
//otherwise we can just call the SP without params
else
{
return ExecuteDataset(transaction, CommandType.StoredProcedure, spName);
}
}
#endregion ExecuteDataSet
#region ExecuteReader
/// <summary>
/// this enum is used to indicate whether the connection was provided by the caller, or created by SqlHelper, so that
/// we can set the appropriate CommandBehavior when calling ExecuteReader()
/// </summary>
private enum SqlConnectionOwnership
{
/// <summary>Connection is owned and managed by SqlHelper</summary>
Internal,
/// <summary>Connection is owned and managed by the caller</summary>
External
}
/// <summary>
/// Create and prepare a SqlCommand, and call ExecuteReader with the appropriate CommandBehavior.
/// </summary>
/// <remarks>
/// If we created and opened the connection, we want the connection to be closed when the DataReader is closed.
///
/// If the caller provided the connection, we want to leave it to them to manage.
/// </remarks>
/// <param name="connection">a valid SqlConnection, on which to execute this command</param>
/// <param name="transaction">a valid SqlTransaction, or 'null'</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <param name="commandParameters">an array of SqlParameters to be associated with the command or 'null' if no parameters are required</param>
/// <param name="connectionOwnership">indicates whether the connection parameter was provided by the caller, or created by SqlHelper</param>
/// <returns>SqlDataReader containing the results of the command</returns>
private static SqlDataReader ExecuteReader(SqlConnection connection, SqlTransaction transaction, CommandType commandType, string commandText, SqlParameter[] commandParameters, SqlConnectionOwnership connectionOwnership)
{
//create a command and prepare it for execution
SqlCommand cmd = new SqlCommand();
PrepareCommand(cmd, connection, transaction, commandType, commandText, commandParameters);
//create a reader
SqlDataReader dr;
// call ExecuteReader with the appropriate CommandBehavior
if (connectionOwnership == SqlConnectionOwnership.External)
{
dr = cmd.ExecuteReader();
}
else
{
dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
// detach the SqlParameters from the command object, so they can be used again.
cmd.Parameters.Clear();
return dr;
}
/// <summary>
/// Execute a SqlCommand (that returns a resultset and takes no parameters) against the database specified in
/// the connection string.
/// </summary>
/// <remarks>
/// e.g.:
/// SqlDataReader dr = ExecuteReader(connString, CommandType.StoredProcedure, "GetOrders");
/// </remarks>
/// <param name="connectionString">a valid connection string for a SqlConnection</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <returns>a SqlDataReader containing the resultset generated by the command</returns>
public static SqlDataReader ExecuteReader(string connectionString, CommandType commandType, string commandText)
{
//pass through the call providing null for the set of SqlParameters
return ExecuteReader(connectionString, commandType, commandText, (SqlParameter[])null);
}
/// <summary>
/// Execute a SqlCommand (that returns a resultset) against the database specified in the connection string
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// SqlDataReader dr = ExecuteReader(connString, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="connectionString">a valid connection string for a SqlConnection</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <param name="commandParameters">an array of SqlParamters used to execute the command</param>
/// <returns>a SqlDataReader containing the resultset generated by the command</returns>
public static SqlDataReader ExecuteReader(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
{
//create & open a SqlConnection
SqlConnection cn = new SqlConnection(connectionString);
cn.Open();
try
{
//call the private overload that takes an internally owned connection in place of the connection string
return ExecuteReader(cn, null, commandType, commandText, commandParameters, SqlConnectionOwnership.Internal);
}
catch (Exception e)
{
//if we fail to return the SqlDatReader, we need to close the connection ourselves
cn.Close();
throw e;
}
}
/// <summary>
/// Execute a stored procedure via a SqlCommand (that returns a resultset) against the database specified in
/// the connection string using the provided parameter values. This method will query the database to discover the parameters for the
/// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
/// </summary>
/// <remarks>
/// This method provides no access to output parameters or the stored procedure's return value parameter.
///
/// e.g.:
/// SqlDataReader dr = ExecuteReader(connString, "GetOrders", 24, 36);
/// </remarks>
/// <param name="connectionString">a valid connection string for a SqlConnection</param>
/// <param name="spName">the name of the stored procedure</param>
/// <param name="parameterValues">an array of objects to be assigned as the input values of the stored procedure</param>
/// <returns>a SqlDataReader containing the resultset generated by the command</returns>
public static SqlDataReader ExecuteReader(string connectionString, string spName, params object[] parameterValues)
{
//if we receive parameter values, we need to figure out where they go
if ((parameterValues != null) && (parameterValues.Length > 0))
{
//pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
//assign the provided values to these parameters based on parameter order
AssignParameterValues(commandParameters, parameterValues);
//call the overload that takes an array of SqlParameters
return ExecuteReader(connectionString, CommandType.StoredProcedure, spName, commandParameters);
}
//otherwise we can just call the SP without params
else
{
return ExecuteReader(connectionString, CommandType.StoredProcedure, spName);
}
}
/// <summary>
/// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlConnection.
/// </summary>
/// <remarks>
/// e.g.:
/// SqlDataReader dr = ExecuteReader(conn, CommandType.StoredProcedure, "GetOrders");
/// </remarks>
/// <param name="connection">a valid SqlConnection</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <returns>a SqlDataReader containing the resultset generated by the command</returns>
public static SqlDataReader ExecuteReader(SqlConnection connection, CommandType commandType, string commandText)
{
//pass through the call providing null for the set of SqlParameters
return ExecuteReader(connection, commandType, commandText, (SqlParameter[])null);
}
/// <summary>
/// Execute a SqlCommand (that returns a resultset) against the specified SqlConnection
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// SqlDataReader dr = ExecuteReader(conn, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="connection">a valid SqlConnection</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <param name="commandParameters">an array of SqlParamters used to execute the command</param>
/// <returns>a SqlDataReader containing the resultset generated by the command</returns>
public static SqlDataReader ExecuteReader(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
{
//pass through the call to the private overload using a null transaction value and an externally owned connection
return ExecuteReader(connection, (SqlTransaction)null, commandType, commandText, commandParameters, SqlConnectionOwnership.External);
}
/// <summary>
/// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlConnection
/// using the provided parameter values. This method will query the database to discover the parameters for the
/// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
/// </summary>
/// <remarks>
/// This method provides no access to output parameters or the stored procedure's return value parameter.
///
/// e.g.:
/// SqlDataReader dr = ExecuteReader(conn, "GetOrders", 24, 36);
/// </remarks>
/// <param name="connection">a valid SqlConnection</param>
/// <param name="spName">the name of the stored procedure</param>
/// <param name="parameterValues">an array of objects to be assigned as the input values of the stored procedure</param>
/// <returns>a SqlDataReader containing the resultset generated by the command</returns>
public static SqlDataReader ExecuteReader(SqlConnection connection, string spName, params object[] parameterValues)
{
//if we receive parameter values, we need to figure out where they go
if ((parameterValues != null) && (parameterValues.Length > 0))
{
SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection.ConnectionString, spName);
AssignParameterValues(commandParameters, parameterValues);
return ExecuteReader(connection, CommandType.StoredProcedure, spName, commandParameters);
}
//otherwise we can just call the SP without params
else
{
return ExecuteReader(connection, CommandType.StoredProcedure, spName);
}
}
/// <summary>
/// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlTransaction.
/// </summary>
/// <remarks>
/// e.g.:
/// SqlDataReader dr = ExecuteReader(trans, CommandType.StoredProcedure, "GetOrders");
/// </remarks>
/// <param name="transaction">a valid SqlTransaction</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <returns>a SqlDataReader containing the resultset generated by the command</returns>
public static SqlDataReader ExecuteReader(SqlTransaction transaction, CommandType commandType, string commandText)
{
//pass through the call providing null for the set of SqlParameters
return ExecuteReader(transaction, commandType, commandText, (SqlParameter[])null);
}
/// <summary>
/// Execute a SqlCommand (that returns a resultset) against the specified SqlTransaction
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// SqlDataReader dr = ExecuteReader(trans, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="transaction">a valid SqlTransaction</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <param name="commandParameters">an array of SqlParamters used to execute the command</param>
/// <returns>a SqlDataReader containing the resultset generated by the command</returns>
public static SqlDataReader ExecuteReader(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
{
//pass through to private overload, indicating that the connection is owned by the caller
return ExecuteReader(transaction.Connection, transaction, commandType, commandText, commandParameters, SqlConnectionOwnership.External);
}
/// <summary>
/// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified
/// SqlTransaction using the provided parameter values. This method will query the database to discover the parameters for the
/// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
/// </summary>
/// <remarks>
/// This method provides no access to output parameters or the stored procedure's return value parameter.
///
/// e.g.:
/// SqlDataReader dr = ExecuteReader(trans, "GetOrders", 24, 36);
/// </remarks>
/// <param name="transaction">a valid SqlTransaction</param>
/// <param name="spName">the name of the stored procedure</param>
/// <param name="parameterValues">an array of objects to be assigned as the input values of the stored procedure</param>
/// <returns>a SqlDataReader containing the resultset generated by the command</returns>
public static SqlDataReader ExecuteReader(SqlTransaction transaction, string spName, params object[] parameterValues)
{
//if we receive parameter values, we need to figure out where they go
if ((parameterValues != null) && (parameterValues.Length > 0))
{
SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection.ConnectionString, spName);
AssignParameterValues(commandParameters, parameterValues);
return ExecuteReader(transaction, CommandType.StoredProcedure, spName, commandParameters);
}
//otherwise we can just call the SP without params
else
{
return ExecuteReader(transaction, CommandType.StoredProcedure, spName);
}
}
#endregion ExecuteReader
#region ExecuteScalar
/// <summary>
/// Execute a SqlCommand (that returns a 1x1 resultset and takes no parameters) against the database specified in
/// the connection string.
/// </summary>
/// <remarks>
/// e.g.:
/// int orderCount = (int)ExecuteScalar(connString, CommandType.StoredProcedure, "GetOrderCount");
/// </remarks>
/// <param name="connectionString">a valid connection string for a SqlConnection</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <returns>an object containing the value in the 1x1 resultset generated by the command</returns>
public static object ExecuteScalar(string connectionString, CommandType commandType, string commandText)
{
//pass through the call providing null for the set of SqlParameters
return ExecuteScalar(connectionString, commandType, commandText, (SqlParameter[])null);
}
/// <summary>
/// Execute a SqlCommand (that returns a 1x1 resultset) against the database specified in the connection string
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// int orderCount = (int)ExecuteScalar(connString, CommandType.StoredProcedure, "GetOrderCount", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="connectionString">a valid connection string for a SqlConnection</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <param name="commandParameters">an array of SqlParamters used to execute the command</param>
/// <returns>an object containing the value in the 1x1 resultset generated by the command</returns>
public static object ExecuteScalar(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
{
//create & open a SqlConnection, and dispose of it after we are done.
using (SqlConnection cn = new SqlConnection(connectionString))
{
cn.Open();
//call the overload that takes a connection in place of the connection string
return ExecuteScalar(cn, commandType, commandText, commandParameters);
}
}
/// <summary>
/// Execute a stored procedure via a SqlCommand (that returns a 1x1 resultset) against the database specified in
/// the connection string using the provided parameter values. This method will query the database to discover the parameters for the
/// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
/// </summary>
/// <remarks>
/// This method provides no access to output parameters or the stored procedure's return value parameter.
///
/// e.g.:
/// int orderCount = (int)ExecuteScalar(connString, "GetOrderCount", 24, 36);
/// </remarks>
/// <param name="connectionString">a valid connection string for a SqlConnection</param>
/// <param name="spName">the name of the stored procedure</param>
/// <param name="parameterValues">an array of objects to be assigned as the input values of the stored procedure</param>
/// <returns>an object containing the value in the 1x1 resultset generated by the command</returns>
public static object ExecuteScalar(string connectionString, string spName, params object[] parameterValues)
{
//if we receive parameter values, we need to figure out where they go
if ((parameterValues != null) && (parameterValues.Length > 0))
{
//pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);
//assign the provided values to these parameters based on parameter order
AssignParameterValues(commandParameters, parameterValues);
//call the overload that takes an array of SqlParameters
return ExecuteScalar(connectionString, CommandType.StoredProcedure, spName, commandParameters);
}
//otherwise we can just call the SP without params
else
{
return ExecuteScalar(connectionString, CommandType.StoredProcedure, spName);
}
}
/// <summary>
/// Execute a SqlCommand (that returns a 1x1 resultset and takes no parameters) against the provided SqlConnection.
/// </summary>
/// <remarks>
/// e.g.:
/// int orderCount = (int)ExecuteScalar(conn, CommandType.StoredProcedure, "GetOrderCount");
/// </remarks>
/// <param name="connection">a valid SqlConnection</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <returns>an object containing the value in the 1x1 resultset generated by the command</returns>
public static object ExecuteScalar(SqlConnection connection, CommandType commandType, string commandText)
{
//pass through the call providing null for the set of SqlParameters
return ExecuteScalar(connection, commandType, commandText, (SqlParameter[])null);
}
/// <summary>
/// Execute a SqlCommand (that returns a 1x1 resultset) against the specified SqlConnection
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// int orderCount = (int)ExecuteScalar(conn, CommandType.StoredProcedure, "GetOrderCount", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="connection">a valid SqlConnection</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <param name="commandParameters">an array of SqlParamters used to execute the command</param>
/// <returns>an object containing the value in the 1x1 resultset generated by the command</returns>
public static object ExecuteScalar(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
{
//create a command and prepare it for execution
SqlCommand cmd = new SqlCommand();
PrepareCommand(cmd, connection, (SqlTransaction)null, commandType, commandText, commandParameters);
//execute the command & return the results
object retval = cmd.ExecuteScalar();
// detach the SqlParameters from the command object, so they can be used again.
cmd.Parameters.Clear();
return retval;
}
/// <summary>
/// Execute a stored procedure via a SqlCommand (that returns a 1x1 resultset) against the specified SqlConnection
/// using the provided parameter values. This method will query the database to discover the parameters for the
/// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
/// </summary>
/// <remarks>
/// This method provides no access to output parameters or the stored procedure's return value parameter.
///
/// e.g.:
/// int orderCount = (int)ExecuteScalar(conn, "GetOrderCount", 24, 36);
/// </remarks>
/// <param name="connection">a valid SqlConnection</param>
/// <param name="spName">the name of the stored procedure</param>
/// <param name="parameterValues">an array of objects to be assigned as the input values of the stored procedure</param>
/// <returns>an object containing the value in the 1x1 resultset generated by the command</returns>
public static object ExecuteScalar(SqlConnection connection, string spName, params object[] parameterValues)
{
//if we receive parameter values, we need to figure out where they go
if ((parameterValues != null) && (parameterValues.Length > 0))
{
//pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection.ConnectionString, spName);
//assign the provided values to these parameters based on parameter order
AssignParameterValues(commandParameters, parameterValues);
//call the overload that takes an array of SqlParameters
return ExecuteScalar(connection, CommandType.StoredProcedure, spName, commandParameters);
}
//otherwise we can just call the SP without params
else
{
return ExecuteScalar(connection, CommandType.StoredProcedure, spName);
}
}
/// <summary>
/// Execute a SqlCommand (that returns a 1x1 resultset and takes no parameters) against the provided SqlTransaction.
/// </summary>
/// <remarks>
/// e.g.:
/// int orderCount = (int)ExecuteScalar(trans, CommandType.StoredProcedure, "GetOrderCount");
/// </remarks>
/// <param name="transaction">a valid SqlTransaction</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <returns>an object containing the value in the 1x1 resultset generated by the command</returns>
public static object ExecuteScalar(SqlTransaction transaction, CommandType commandType, string commandText)
{
//pass through the call providing null for the set of SqlParameters
return ExecuteScalar(transaction, commandType, commandText, (SqlParameter[])null);
}
/// <summary>
/// Execute a SqlCommand (that returns a 1x1 resultset) against the specified SqlTransaction
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// int orderCount = (int)ExecuteScalar(trans, CommandType.StoredProcedure, "GetOrderCount", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="transaction">a valid SqlTransaction</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <param name="commandParameters">an array of SqlParamters used to execute the command</param>
/// <returns>an object containing the value in the 1x1 resultset generated by the command</returns>
public static object ExecuteScalar(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
{
//create a command and prepare it for execution
SqlCommand cmd = new SqlCommand();
PrepareCommand(cmd, transaction.Connection, transaction, commandType, commandText, commandParameters);
//execute the command & return the results
object retval = cmd.ExecuteScalar();
// detach the SqlParameters from the command object, so they can be used again.
cmd.Parameters.Clear();
return retval;
}
/// <summary>
/// Execute a stored procedure via a SqlCommand (that returns a 1x1 resultset) against the specified
/// SqlTransaction using the provided parameter values. This method will query the database to discover the parameters for the
/// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
/// </summary>
/// <remarks>
/// This method provides no access to output parameters or the stored procedure's return value parameter.
///
/// e.g.:
/// int orderCount = (int)ExecuteScalar(trans, "GetOrderCount", 24, 36);
/// </remarks>
/// <param name="transaction">a valid SqlTransaction</param>
/// <param name="spName">the name of the stored procedure</param>
/// <param name="parameterValues">an array of objects to be assigned as the input values of the stored procedure</param>
/// <returns>an object containing the value in the 1x1 resultset generated by the command</returns>
public static object ExecuteScalar(SqlTransaction transaction, string spName, params object[] parameterValues)
{
//if we receive parameter values, we need to figure out where they go
if ((parameterValues != null) && (parameterValues.Length > 0))
{
//pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection.ConnectionString, spName);
//assign the provided values to these parameters based on parameter order
AssignParameterValues(commandParameters, parameterValues);
//call the overload that takes an array of SqlParameters
return ExecuteScalar(transaction, CommandType.StoredProcedure, spName, commandParameters);
}
//otherwise we can just call the SP without params
else
{
return ExecuteScalar(transaction, CommandType.StoredProcedure, spName);
}
}
#endregion ExecuteScalar
#region ExecuteXmlReader
/// <summary>
/// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlConnection.
/// </summary>
/// <remarks>
/// e.g.:
/// XmlReader r = ExecuteXmlReader(conn, CommandType.StoredProcedure, "GetOrders");
/// </remarks>
/// <param name="connection">a valid SqlConnection</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command using "FOR XML AUTO"</param>
/// <returns>an XmlReader containing the resultset generated by the command</returns>
public static XmlReader ExecuteXmlReader(SqlConnection connection, CommandType commandType, string commandText)
{
//pass through the call providing null for the set of SqlParameters
return ExecuteXmlReader(connection, commandType, commandText, (SqlParameter[])null);
}
/// <summary>
/// Execute a SqlCommand (that returns a resultset) against the specified SqlConnection
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// XmlReader r = ExecuteXmlReader(conn, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="connection">a valid SqlConnection</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command using "FOR XML AUTO"</param>
/// <param name="commandParameters">an array of SqlParamters used to execute the command</param>
/// <returns>an XmlReader containing the resultset generated by the command</returns>
public static XmlReader ExecuteXmlReader(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
{
//create a command and prepare it for execution
SqlCommand cmd = new SqlCommand();
PrepareCommand(cmd, connection, (SqlTransaction)null, commandType, commandText, commandParameters);
//create the DataAdapter & DataSet
XmlReader retval = cmd.ExecuteXmlReader();
// detach the SqlParameters from the command object, so they can be used again.
cmd.Parameters.Clear();
return retval;
}
/// <summary>
/// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlConnection
/// using the provided parameter values. This method will query the database to discover the parameters for the
/// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
/// </summary>
/// <remarks>
/// This method provides no access to output parameters or the stored procedure's return value parameter.
///
/// e.g.:
/// XmlReader r = ExecuteXmlReader(conn, "GetOrders", 24, 36);
/// </remarks>
/// <param name="connection">a valid SqlConnection</param>
/// <param name="spName">the name of the stored procedure using "FOR XML AUTO"</param>
/// <param name="parameterValues">an array of objects to be assigned as the input values of the stored procedure</param>
/// <returns>an XmlReader containing the resultset generated by the command</returns>
public static XmlReader ExecuteXmlReader(SqlConnection connection, string spName, params object[] parameterValues)
{
//if we receive parameter values, we need to figure out where they go
if ((parameterValues != null) && (parameterValues.Length > 0))
{
//pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection.ConnectionString, spName);
//assign the provided values to these parameters based on parameter order
AssignParameterValues(commandParameters, parameterValues);
//call the overload that takes an array of SqlParameters
return ExecuteXmlReader(connection, CommandType.StoredProcedure, spName, commandParameters);
}
//otherwise we can just call the SP without params
else
{
return ExecuteXmlReader(connection, CommandType.StoredProcedure, spName);
}
}
/// <summary>
/// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlTransaction.
/// </summary>
/// <remarks>
/// e.g.:
/// XmlReader r = ExecuteXmlReader(trans, CommandType.StoredProcedure, "GetOrders");
/// </remarks>
/// <param name="transaction">a valid SqlTransaction</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command using "FOR XML AUTO"</param>
/// <returns>an XmlReader containing the resultset generated by the command</returns>
public static XmlReader ExecuteXmlReader(SqlTransaction transaction, CommandType commandType, string commandText)
{
//pass through the call providing null for the set of SqlParameters
return ExecuteXmlReader(transaction, commandType, commandText, (SqlParameter[])null);
}
/// <summary>
/// Execute a SqlCommand (that returns a resultset) against the specified SqlTransaction
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// XmlReader r = ExecuteXmlReader(trans, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="transaction">a valid SqlTransaction</param>
/// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">the stored procedure name or T-SQL command using "FOR XML AUTO"</param>
/// <param name="commandParameters">an array of SqlParamters used to execute the command</param>
/// <returns>an XmlReader containing the resultset generated by the command</returns>
public static XmlReader ExecuteXmlReader(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
{
//create a command and prepare it for execution
SqlCommand cmd = new SqlCommand();
PrepareCommand(cmd, transaction.Connection, transaction, commandType, commandText, commandParameters);
//create the DataAdapter & DataSet
XmlReader retval = cmd.ExecuteXmlReader();
// detach the SqlParameters from the command object, so they can be used again.
cmd.Parameters.Clear();
return retval;
}
/// <summary>
/// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified
/// SqlTransaction using the provided parameter values. This method will query the database to discover the parameters for the
/// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
/// </summary>
/// <remarks>
/// This method provides no access to output parameters or the stored procedure's return value parameter.
///
/// e.g.:
/// XmlReader r = ExecuteXmlReader(trans, "GetOrders", 24, 36);
/// </remarks>
/// <param name="transaction">a valid SqlTransaction</param>
/// <param name="spName">the name of the stored procedure</param>
/// <param name="parameterValues">an array of objects to be assigned as the input values of the stored procedure</param>
/// <returns>a dataset containing the resultset generated by the command</returns>
public static XmlReader ExecuteXmlReader(SqlTransaction transaction, string spName, params object[] parameterValues)
{
//if we receive parameter values, we need to figure out where they go
if ((parameterValues != null) && (parameterValues.Length > 0))
{
//pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection.ConnectionString, spName);
//assign the provided values to these parameters based on parameter order
AssignParameterValues(commandParameters, parameterValues);
//call the overload that takes an array of SqlParameters
return ExecuteXmlReader(transaction, CommandType.StoredProcedure, spName, commandParameters);
}
//otherwise we can just call the SP without params
else
{
return ExecuteXmlReader(transaction, CommandType.StoredProcedure, spName);
}
}
#endregion ExecuteXmlReader
}
/// <summary>
/// SqlHelperParameterCache provides functions to leverage a static cache of procedure parameters, and the
/// ability to discover parameters for stored procedures at run-time.
/// </summary>
public sealed class SqlHelperParameterCache
{
#region private methods, variables, and constructors
//Since this class provides only static methods, make the default constructor private to prevent
//instances from being created with "new SqlHelperParameterCache()".
private SqlHelperParameterCache() { }
private static Hashtable paramCache = Hashtable.Synchronized(new Hashtable());
/// <summary>
/// resolve at run time the appropriate set of SqlParameters for a stored procedure
/// </summary>
/// <param name="connectionString">a valid connection string for a SqlConnection</param>
/// <param name="spName">the name of the stored procedure</param>
/// <param name="includeReturnValueParameter">whether or not to include their return value parameter</param>
/// <returns></returns>
private static SqlParameter[] DiscoverSpParameterSet(string connectionString, string spName, bool includeReturnValueParameter)
{
using (SqlConnection cn = new SqlConnection(connectionString))
using (SqlCommand cmd = new SqlCommand(spName, cn))
{
cn.Open();
cmd.CommandType = CommandType.StoredProcedure;
SqlCommandBuilder.DeriveParameters(cmd);
if (!includeReturnValueParameter)
{
cmd.Parameters.RemoveAt(0);
}
SqlParameter[] discoveredParameters = new SqlParameter[cmd.Parameters.Count]; ;
cmd.Parameters.CopyTo(discoveredParameters, 0);
return discoveredParameters;
}
}
//deep copy of cached SqlParameter array
private static SqlParameter[] CloneParameters(SqlParameter[] originalParameters)
{
SqlParameter[] clonedParameters = new SqlParameter[originalParameters.Length];
for (int i = 0, j = originalParameters.Length; i < j; i++)
{
clonedParameters[i] = (SqlParameter)((ICloneable)originalParameters[i]).Clone();
}
return clonedParameters;
}
#endregion private methods, variables, and constructors
#region caching functions
/// <summary>
/// add parameter array to the cache
/// </summary>
/// <param name="connectionString">a valid connection string for a SqlConnection</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <param name="commandParameters">an array of SqlParamters to be cached</param>
public static void CacheParameterSet(string connectionString, string commandText, params SqlParameter[] commandParameters)
{
string hashKey = connectionString + ":" + commandText;
paramCache[hashKey] = commandParameters;
}
/// <summary>
/// retrieve a parameter array from the cache
/// </summary>
/// <param name="connectionString">a valid connection string for a SqlConnection</param>
/// <param name="commandText">the stored procedure name or T-SQL command</param>
/// <returns>an array of SqlParamters</returns>
public static SqlParameter[] GetCachedParameterSet(string connectionString, string commandText)
{
string hashKey = connectionString + ":" + commandText;
SqlParameter[] cachedParameters = (SqlParameter[])paramCache[hashKey];
if (cachedParameters == null)
{
return null;
}
else
{
return CloneParameters(cachedParameters);
}
}
#endregion caching functions
#region Parameter Discovery Functions
/// <summary>
/// Retrieves the set of SqlParameters appropriate for the stored procedure
/// </summary>
/// <remarks>
/// This method will query the database for this information, and then store it in a cache for future requests.
/// </remarks>
/// <param name="connectionString">a valid connection string for a SqlConnection</param>
/// <param name="spName">the name of the stored procedure</param>
/// <returns>an array of SqlParameters</returns>
public static SqlParameter[] GetSpParameterSet(string connectionString, string spName)
{
return GetSpParameterSet(connectionString, spName, false);
}
/// <summary>
/// Retrieves the set of SqlParameters appropriate for the stored procedure
/// </summary>
/// <remarks>
/// This method will query the database for this information, and then store it in a cache for future requests.
/// </remarks>
/// <param name="connectionString">a valid connection string for a SqlConnection</param>
/// <param name="spName">the name of the stored procedure</param>
/// <param name="includeReturnValueParameter">a bool value indicating whether the return value parameter should be included in the results</param>
/// <returns>an array of SqlParameters</returns>
public static SqlParameter[] GetSpParameterSet(string connectionString, string spName, bool includeReturnValueParameter)
{
string hashKey = connectionString + ":" + spName + (includeReturnValueParameter ? ":include ReturnValue Parameter" : "");
SqlParameter[] cachedParameters;
cachedParameters = (SqlParameter[])paramCache[hashKey];
if (cachedParameters == null)
{
cachedParameters = (SqlParameter[])(paramCache[hashKey] = DiscoverSpParameterSet(connectionString, spName, includeReturnValueParameter));
}
return CloneParameters(cachedParameters);
}
#endregion Parameter Discovery Functions
}
}
using System.Collections.Generic;
using System.Data;
using System.Text;
using System.Data.SqlClient;
namespace test.Extension
{
public static partial class DataTableExtension
{
public static List<string> GetFields(this DataTable dataTable)
{
List<string> lstFieldName = new List<string>();
foreach (DataColumn column in dataTable.Columns)
{
lstFieldName.Add(column.ColumnName);
}
return lstFieldName;
}
public static string GetInsertCommand(this DataTable dataTable, string tableName)
{
List<string> lstFieldName = dataTable.GetFields();
StringBuilder sb = new StringBuilder();
sb.Append(" INSERT INTO ");
sb.Append(tableName);
sb.Append(" ( ");
sb.Append(lstFieldName.JoinString(","));
sb.Append(") values (");
sb.Append("@");
sb.Append(lstFieldName.JoinString(",@"));
sb.Append(")");
return sb.ToString();
}
public static string GetUpdateCommand(List<string> tabColumns, string tableName, string primaryKeyName)
{
List<string> lstFieldName = new List<string>();
tabColumns.ForEach(field =>
{
if (field != primaryKeyName) lstFieldName.Add($"{field} = @{field}");
});
StringBuilder sb = new StringBuilder();
sb.Append(" Update ");
sb.Append(tableName);
sb.Append(" Set ");
sb.Append(lstFieldName.JoinString(","));
sb.Append($" Where {primaryKeyName} = @{primaryKeyName};");
return sb.ToString();
}
public static string GetUpdateCommand(this DataTable dataTable, string tableName, string primaryKeyName)
{
List<string> lstFieldName = new List<string>();
foreach (DataColumn column in dataTable.Columns)
{
if (column.ColumnName == primaryKeyName) continue;
lstFieldName.Add($"{column.ColumnName} = @{column.ColumnName}");
}
StringBuilder sb = new StringBuilder();
sb.Append(" Update ");
sb.Append(tableName);
sb.Append(" Set ");
sb.Append(lstFieldName.JoinString(","));
sb.Append($" Where {primaryKeyName} = @{primaryKeyName};");
return sb.ToString();
}
public static KeyValuePair<string, IEnumerable<Dictionary<string, object>>> GetInsertCommandWithParam(this DataTable dataTable, string tableName)
{
return new KeyValuePair<string, IEnumerable<Dictionary<string, object>>>(dataTable.GetInsertCommand(tableName), dataTable.GetFieldValues());
}
public static IEnumerable<Dictionary<string, object>> GetFieldValues(this DataTable dataTable)
{
var lstDic = new List<Dictionary<string, object>>();
for (var i = 0; i < dataTable.Rows.Count; i++)
{
var row = dataTable.Rows[i];
var dic = new Dictionary<string, object>();
for (var j = 0; j < dataTable.Columns.Count; j++)
{
var oValue = row[j];
dic.Add(dataTable.Columns[j].ColumnName, oValue != System.DBNull.Value ? oValue : null);
}
lstDic.Add(dic);
}
return lstDic;
}
public static List<SqlParameter[]> GetSqlParameter(this DataTable dataTable)
{
var lstParam = new List<SqlParameter[]>();
for (var i = 0; i < dataTable.Rows.Count; i++)
{
var parameters = new List<SqlParameter>();
for (var j = 0; j < dataTable.Columns.Count; j++)
{
parameters.Add(new SqlParameter(dataTable.Columns[j].ColumnName, dataTable.Rows[i][j]));
}
lstParam.Add(parameters.ToArray());
}
return lstParam;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
namespace test.Extension
{
public static class ExpressionExtension
{
public struct BinaryExpressionInfo
{
public BinaryExpression Body;
public MemberExpression Left;
public Expression Right;
public string LeftName;
public object GetRightValue()
{
if (this.Right is MemberExpression)
{
return this.getMemberExpressionValue((MemberExpression)this.Right);
}
if (this.Right is ConstantExpression)
{
return this.getConstantExpressionValue((ConstantExpression)this.Right);
}
throw new Exception("未实现的Expression类型:" + this.Right.GetType().FullName);
}
private object getConstantExpressionValue(ConstantExpression r)
{
return r.Value;
}
private object getMemberExpressionValue(MemberExpression r)
{
if (r.Expression is ConstantExpression)
{
object rightValue = ((ConstantExpression)r.Expression).Value;
return ((FieldInfo)r.Member).GetValue(rightValue);
}
if (r.Expression is MemberExpression)
{
return Expression.Lambda(r, new ParameterExpression[0]).Compile().DynamicInvoke(new object[0]);
}
throw new Exception("未能处理表达式的右侧的值");
}
}
public static string GetOneName(this Expression exp)
{
return ((PropertyInfo)((MemberExpression)((LambdaExpression)exp).Body).Member).Name;
}
public static ExpressionExtension.BinaryExpressionInfo GetBinaryExpressionInfo(this Expression exp)
{
ExpressionExtension.BinaryExpressionInfo info = default(ExpressionExtension.BinaryExpressionInfo);
info.Body = (BinaryExpression)((LambdaExpression)exp).Body;
info.Left = (MemberExpression)info.Body.Left;
info.Right = info.Body.Right;
info.LeftName = info.Left.Member.Name;
return info;
}
public static string JoinString<T>(this IEnumerable<T> source, string separator)
{
return string.Join<T>(separator, source);
}
}
}
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace test.Extension
{
public static partial class DataTableExtension
{
#region 公共方法(扩展DataTable)
/// <summary>
/// DataTable转换成T
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
/// <param name="table">需转换的数据table</param>
/// <returns></returns>
public static T ToModel<T>(this DataTable table) where T : new()
{
if (table == null || table.Columns.Count == 0 || table.Rows.Count == 0) return default(T);
var propertyInfos = from propertyInfo in typeof(T).GetProperties()
where table.Columns.Contains(propertyInfo.Name)
select propertyInfo;
return DataRowToModel<T>(propertyInfos, table.Rows[0]);
//T entity = new T();
//DataRow dr = table.Rows[0];
//foreach (var pi in propertyInfos)
//{
// if (!pi.CanWrite) continue;
// object value = dr[pi.Name];
// if (value != DBNull.Value)
// pi.SetValue(entity, ChangeType(dr[pi.Name], pi.PropertyType), null);
//}
//return entity;
}
/// <summary>
/// DataTable转换成List<T>
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
/// <param name="table">需转换的数据table</param>
/// <returns></returns>
public static List<T> ToModelList<T>(this DataTable table) where T : new()
{
List<T> entities = new List<T>();
if (table == null || table.Columns.Count == 0 || table.Rows.Count == 0) return entities;
var propertyInfos = from propertyInfo in typeof(T).GetProperties()
where table.Columns.Contains(propertyInfo.Name)
select propertyInfo;
foreach (DataRow dr in table.Rows)
{
entities.Add(DataRowToModel<T>(propertyInfos, dr));
}
return entities;
//foreach (DataRow dr in table.Rows)
//{
// T entity = new T();
// foreach (var pi in propertyInfos)
// {
// if (!pi.CanWrite) continue;
// object value = dr[pi.Name];
// if (value != DBNull.Value)
// pi.SetValue(entity, ChangeType(dr[pi.Name], pi.PropertyType), null);
// }
// entities.Add(entity);
//}
//return entities;
}
#endregion 公共方法(扩展DataTable)
#region 私有方法(Convert.ChangeType处理Nullable<>和非Nullable<>)
private static T DataRowToModel<T>(IEnumerable<System.Reflection.PropertyInfo> propertyInfos, DataRow dataRow) where T : new()
{
T entity = new T();
foreach (var pi in propertyInfos)
{
if (!pi.CanWrite) continue;
object value = dataRow[pi.Name];
if (value != DBNull.Value || pi.PropertyType == typeof(string)) // 为null的字符串需要转化为""
pi.SetValue(entity, ChangeType(dataRow[pi.Name], pi.PropertyType), null);
}
return entity;
}
/// <summary>
/// 类型转换(包含Nullable<>和非Nullable<>转换)
/// </summary>
/// <param name="value"></param>
/// <param name="conversionType"></param>
/// <returns></returns>
private static object ChangeType(object value, Type conversionType)
{
// Note: This if block was taken from Convert.ChangeType as is, and is needed here since we're
// checking properties on conversionType below.
if (conversionType == null)
{
throw new ArgumentNullException("conversionType");
} // end if
// If it's not a nullable type, just pass through the parameters to Convert.ChangeType
if (conversionType.IsGenericType &&
conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
{
if (value == null)
{
return null;
}
// It's a nullable type, and not null, so that means it can be converted to its underlying type,
// so overwrite the passed-in conversion type with this underlying type
System.ComponentModel.NullableConverter nullableConverter = new System.ComponentModel.NullableConverter(conversionType);
conversionType = nullableConverter.UnderlyingType;
}
// Now that we've guaranteed conversionType is something Convert.ChangeType can handle (i.e. not a
// nullable type), pass the call on to Convert.ChangeType
return Convert.ChangeType(value, conversionType);
}
#endregion 私有方法(Convert.ChangeType处理Nullable<>和非Nullable<>)
}
}

namespace test
{
partial class FrmDbo
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.btnDapper = new System.Windows.Forms.Button();
this.btnFluent = new System.Windows.Forms.Button();
this.btnSqlHelper = new System.Windows.Forms.Button();
this.textBox1 = new System.Windows.Forms.TextBox();
this.btnClear = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// btnDapper
//
this.btnDapper.Location = new System.Drawing.Point(25, 23);
this.btnDapper.Name = "btnDapper";
this.btnDapper.Size = new System.Drawing.Size(75, 23);
this.btnDapper.TabIndex = 1;
this.btnDapper.Text = "RunDraaper";
this.btnDapper.UseVisualStyleBackColor = true;
this.btnDapper.Click += new System.EventHandler(this.btnDapper_Click);
//
// btnFluent
//
this.btnFluent.Location = new System.Drawing.Point(128, 23);
this.btnFluent.Name = "btnFluent";
this.btnFluent.Size = new System.Drawing.Size(75, 23);
this.btnFluent.TabIndex = 2;
this.btnFluent.Text = "RunFluent";
this.btnFluent.UseVisualStyleBackColor = true;
this.btnFluent.Click += new System.EventHandler(this.btnFluent_Click);
//
// btnSqlHelper
//
this.btnSqlHelper.Location = new System.Drawing.Point(231, 23);
this.btnSqlHelper.Name = "btnSqlHelper";
this.btnSqlHelper.Size = new System.Drawing.Size(75, 23);
this.btnSqlHelper.TabIndex = 3;
this.btnSqlHelper.Text = "RunSqlHelper";
this.btnSqlHelper.UseVisualStyleBackColor = true;
this.btnSqlHelper.Click += new System.EventHandler(this.btnSqlHelper_Click);
//
// textBox1
//
this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.textBox1.Location = new System.Drawing.Point(12, 55);
this.textBox1.Multiline = true;
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(420, 241);
this.textBox1.TabIndex = 4;
//
// btnClear
//
this.btnClear.Location = new System.Drawing.Point(335, 23);
this.btnClear.Name = "btnClear";
this.btnClear.Size = new System.Drawing.Size(75, 23);
this.btnClear.TabIndex = 5;
this.btnClear.Text = "清空";
this.btnClear.UseVisualStyleBackColor = true;
this.btnClear.Click += new System.EventHandler(this.btnClear_Click);
//
// FrmDbo
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(444, 308);
this.Controls.Add(this.btnClear);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.btnSqlHelper);
this.Controls.Add(this.btnFluent);
this.Controls.Add(this.btnDapper);
this.Name = "FrmDbo";
this.Text = "FrmOrm";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button btnDapper;
private System.Windows.Forms.Button btnFluent;
private System.Windows.Forms.Button btnSqlHelper;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.Button btnClear;
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using System.Windows.Forms;
using test.Extension;
using test.Tester;
namespace test
{
public partial class FrmDbo : Form
{
public FrmDbo()
{
InitializeComponent();
}
private void btnQuery_Click(object sender, EventArgs e)
{
ITester tester = new TDapper();
DataTable dtBom = null;
TimeWatch.Wrap("获取Bom5000", () => { dtBom = tester.GetDataTable("Select top(5000) * From OrderStyleBOM"); });
var sql = "Update OrderStyleBOM Set SubmitDate = @SubmitDate,LastModifiedMemo = @LastModifiedMemo,Remark = @Remark Where UID = @UID";
Dictionary<string, object> data = new Dictionary<string, object>() { { "SubmitDate", DateTime.Now }, { "LastModifiedMemo", "更新测试" }, { "UID", Guid.Parse("F25701F7-D877-46CB-986D-991090168B97") }, { "Remark", null } };
tester.Execute(sql, data);
var upCommand = dtBom.GetUpdateCommand("OrderStyleBOM", "UID");
tester.Update(upCommand, dtBom);
var dtInsert = tester.GetDataTable("Select top(100) * From OrderStyleBOM order by ID");
foreach (DataRow row in dtInsert.Rows)
{
row["UID"] = Guid.NewGuid();
}
var insertCommand = dtBom.GetInsertCommand("OrderStyleBOM");
tester.Insert(insertCommand, dtInsert);
}
private void btnDapper_Click(object sender, EventArgs e)
{
ITester tester = new TDapper();
Tester(sender, tester);
}
private void btnFluent_Click(object sender, EventArgs e)
{
ITester tester = new TFluentData();
Tester(sender, tester);
}
private void btnSqlHelper_Click(object sender, EventArgs e)
{
ITester tester = new TSqlHelper();
Tester(sender, tester);
}
private void Tester(object sender, ITester tester)
{
var button = (Button)sender;
button.Enabled = false;
Test1(tester);
button.Enabled = true;
}
private void Test1(ITester tester)
{
dicTimes.Clear();
TimeWatch timeWatch = TimeWatch.Start();
var sql = "Update OrderStyleBOM Set SubmitDate = @SubmitDate,LastModifiedMemo = @LastModifiedMemo,Remark = @Remark Where UID = @UID";
Dictionary<string, object> data = new Dictionary<string, object>() { { "SubmitDate", DateTime.Now }, { "LastModifiedMemo", "更新测试" }, { "UID", Guid.Parse("F25701F7-D877-46CB-986D-991090168B97") }, { "Remark", null } };
tester.Execute(sql, data);
ShowTestTime("更新1条记录", timeWatch);
#region Select 5000
DataTable dtBom = tester.GetDataTable("Select top(5000) * From OrderStyleBOM");
ShowTestTime("查询5000条记录", timeWatch);
#endregion
var dtQuery = tester.GetDataTable("Select top(100) * From OrderStyleBOM order by ID");
#region Update 100
var upCommand = dtBom.GetUpdateCommand("OrderStyleBOM", "UID");
tester.Update(upCommand, dtQuery);
ShowTestTime("更新100条记录", timeWatch);
#endregion
#region Insert 100
foreach (DataRow row in dtQuery.Rows) row["UID"] = Guid.NewGuid(); //
tester.Insert(dtQuery.GetInsertCommand("OrderStyleBOM"), dtQuery);
ShowTestTime("插入100条记录", timeWatch);
#endregion
ShowTester(tester.GetType().Name);
}
Dictionary<string, double> dicTimes = new Dictionary<string, double>();
private void ShowTestTime(string text, TimeWatch timeWatch)
{
dicTimes.Add(text, timeWatch.TimeSpan.TotalMilliseconds);
timeWatch.ShowLog(text, true);
}
private void ShowTester(string testerName)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine($"{ testerName} 测试完成:");
foreach (var dic in dicTimes)
sb.AppendLine($"{dic.Key} 耗时:{dic.Value}");
sb.AppendLine("================================================");
textBox1.Text += sb.ToString();
}
private void btnClear_Click(object sender, EventArgs e)
{
textBox1.Text = "";
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace test
{
static class Program
{
/*
* 抛出异常:
托管调试助手 "ContextSwitchDeadlock"
CLR 无法从 COM 上下文 0xa62c80 转换为 COM 上下文 0xa62b10,这种状态已持续 60 秒。拥有目标上下文/单元的线程很有可能执行的是非泵式等待或者在不发送 Windows 消息的情况下处理一个运行时间非常长的操作。
这种情况通常会影响到性能,甚至可能导致应用程序不响应或者使用的内存随时间不断累积。要避免此问题,所有单线程单元(STA)线程都应使用泵式等待基元(如 CoWaitForMultipleHandles),并在运行时间很长的操作过程中定期发送消息。
在调试菜单中的异常选项,在Managed Debugging Assistants 中将ContextSwitchDeadlock后面的第一个勾给去掉就可以了。
*/
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new FrmDbo());
}
}
}
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("test")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("test")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2021")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("1447f8df-e552-40dd-8f02-b55d75fbc77a")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.42000
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace test.Properties {
using System;
/// <summary>
/// 一个强类型的资源类,用于查找本地化的字符串等。
/// </summary>
// 此类是由 StronglyTypedResourceBuilder
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
// (以 /str 作为命令选项),或重新生成 VS 项目。
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// 返回此类使用的缓存的 ResourceManager 实例。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("test.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// 重写当前线程的 CurrentUICulture 属性,对
/// 使用此强类型资源类的所有资源查找执行重写。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
\ No newline at end of file
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.42000
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace test.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.8.1.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>
using Dapper;
using System;
using System.Collections.Generic;
using System.Data;
using test.DBO;
using test.Extension;
namespace test.Tester
{
public class TDapper : ITester
{
public void Delete(List<int> ids)
{
throw new NotImplementedException();
}
public DataTable GetDataTable(string sql)
{
using (DbDapper dbDapper = new DbDapper(TData.Conn))
{
return dbDapper.GetDataTable(sql);
}
}
public void Execute(string sql, Dictionary<string, object> param)
{
using (DbDapper dbDapper = new DbDapper(TData.Conn))
{
dbDapper.Trans((conn, tran) =>
{
conn.Execute(sql, param, tran);
});
}
}
/// <summary>
/// 经测试 7K 的时候.默认30s不够用
///
/// </summary>
/// <param name="sql"></param>
/// <param name="dataTable"></param>
public void Update(string sql, DataTable dataTable)
{
var lstFieldValues = dataTable.GetFieldValues();
using (DbDapper dbDapper = new DbDapper(TData.Conn))
{
dbDapper.Trans((conn, tran) =>
{
foreach (var item in lstFieldValues)
conn.Execute(sql, item, tran);
});
}
}
public void Insert(string sql, DataTable dataTable)
{
var lstFieldValues = dataTable.GetFieldValues();
using (DbDapper dbDapper = new DbDapper(TData.Conn))
{
dbDapper.Trans((conn, tran) =>
{
foreach (var item in lstFieldValues)
conn.Execute(sql, item, tran);
});
}
}
}
}
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace test.Tester
{
/// <summary>
/// 数据测试,环境可以认为是相同的
/// </summary>
public class TData
{
/// <summary>
/// 测试用到的表
/// </summary>
public static List<string> Tables = new List<string>() { "OrderStyleBOM", "MaterialCalculation", "MX_Material", "OrderSendProjectWorkMaterial", "OrderStyleMaterial", "MaterialCalculationDetail" };
/// <summary>
/// 数据库连接
/// </summary>
public const string Conn = "Password=sa;Persist Security Info=True;User ID=sa;Initial Catalog=tempdb;Data Source=jhdsoft.gicp.net,3204";
}
/// <summary>
/// 需要测试的项目
/// </summary>
public interface ITester
{
DataTable GetDataTable(string sql);
void Execute(string sql, Dictionary<string, object> param);
void Insert(string sql, DataTable dataTable);
void Update(string sql, DataTable dataTable);
void Delete(List<int> ids);
}
}
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FluentData;
using test.DBO;
using test.Extension;
namespace test.Tester
{
public class TFluentData : ITester
{
public void Delete(List<int> ids)
{
throw new NotImplementedException();
}
public void Execute(string sql, Dictionary<string, object> param)
{
DbFluentData dbFluentData = new DbFluentData(TData.Conn);
dbFluentData.Execute(sql, param);
}
public DataTable GetDataTable(string sql)
{
DbFluentData dbFluentData = new DbFluentData(TData.Conn);
var tables = dbFluentData.SelectMany<DataTable>(sql, null);
return tables.Count > 0 ? tables[0] : null;
}
public void Insert(string sql, DataTable dataTable)
{
var lstFieldValues = dataTable.GetFieldValues();
DbFluentData dbFluentData = new DbFluentData(TData.Conn);
dbFluentData.Execute(sql, lstFieldValues);
}
public void Update(string sql, DataTable dataTable)
{
var lstFieldValues = dataTable.GetFieldValues();
DbFluentData dbFluentData = new DbFluentData(TData.Conn);
dbFluentData.Execute(sql, lstFieldValues);
}
}
}
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using test.DBO;
using test.Extension;
namespace test.Tester
{
public class TSqlHelper : ITester
{
public void Delete(List<int> ids)
{
}
public void Execute(string sql, Dictionary<string, object> param)
{
var parameters = ParseDic(param);
DbSqlHelper.ExecuteNonQuery(TData.Conn, CommandType.Text, sql, parameters);
}
public DataTable GetDataTable(string sql)
{
var dataSet = DbSqlHelper.ExecuteDataset(TData.Conn, CommandType.Text, sql);
return dataSet.Tables[0];
}
public void Insert(string sql, DataTable dataTable)
{
var lstParam = dataTable.GetSqlParameter();
using (SqlConnection cn = new SqlConnection(TData.Conn))
{
cn.Open();
var tran = cn.BeginTransaction();
foreach (var param in lstParam)
{
DbSqlHelper.ExecuteNonQuery(tran, CommandType.Text, sql, param);
}
}
}
public void Update(string sql, DataTable dataTable)
{
var lstParam = dataTable.GetSqlParameter();
using (SqlConnection cn = new SqlConnection(TData.Conn))
{
cn.Open();
var tran = cn.BeginTransaction();
foreach (var param in lstParam)
{
DbSqlHelper.ExecuteNonQuery(tran, CommandType.Text, sql, param);
}
}
}
private SqlParameter[] ParseDic(Dictionary<string, object> param)
{
List<SqlParameter> parameters = new List<SqlParameter>();
foreach (var dic in param)
parameters.Add(new SqlParameter(dic.Key, dic.Value ?? System.DBNull.Value));
return parameters.ToArray();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace test
{
public class TimeWatch
{
private DateTime? dtStart, dtEnd;
public static TimeWatch Start()
{
return new TimeWatch();
}
private TimeWatch()
{
ReStart();
}
public void Stop()
{
dtEnd = DateTime.Now;
}
/// <summary>
/// 时间间隔
/// </summary>
public TimeSpan TimeSpan
{
get
{
return (TimeSpan)((dtEnd == null ? DateTime.Now : dtEnd) - dtStart);
}
}
public void ReStart()
{
dtStart = DateTime.Now;
}
public void ShowLog(string text, bool isReset = false)
{
ShowTime(text, this);
if (isReset) ReStart();
}
/// <summary>
/// 写测试日志
/// </summary>
/// <param name="name"></param>
/// <param name="action"></param>
public static void Wrap(string name, Action action)
{
var watch = TimeWatch.Start();
action();
ShowTime(name, watch);
}
private static void ShowTime(string name, TimeWatch timeWatch)
{
Console.WriteLine($"【{name}】:{timeWatch.TimeSpan.TotalMilliseconds} ms");
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Dapper" version="2.0.78" targetFramework="net472" />
<package id="FluentData" version="3.0.1.0" targetFramework="net472" />
</packages>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{1447F8DF-E552-40DD-8F02-B55D75FBC77A}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>test</RootNamespace>
<AssemblyName>test</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Dapper, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapper.2.0.78\lib\net461\Dapper.dll</HintPath>
</Reference>
<Reference Include="FluentData, Version=3.0.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\FluentData.3.0.1.0\lib\FluentData.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL" />
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="DBO\DbFluentData.cs" />
<Compile Include="DBO\DbSqlHelper.cs" />
<Compile Include="Extension\DataTableExtension.cs" />
<Compile Include="Extension\ExpressionExtension.cs" />
<Compile Include="Extension\Table2Model.cs" />
<Compile Include="FrmDbo.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="FrmDbo.Designer.cs">
<DependentUpon>FrmDbo.cs</DependentUpon>
</Compile>
<Compile Include="DBO\DbDapper.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Tester\TDapper.cs" />
<Compile Include="Tester\TFluentData.cs" />
<Compile Include="Tester\TSqlHelper.cs" />
<Compile Include="Tester\TData.cs" />
<Compile Include="TimeWatch.cs" />
<EmbeddedResource Include="FrmDbo.resx">
<DependentUpon>FrmDbo.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment