@ -1,6 +1,4 @@
#if NETFRAMEWORK
/* 2021.09.23 */
/* 2021.10.14 */
using Apewer ;
using Apewer.Source ;
@ -8,88 +6,74 @@ using System;
using System.Collections.Generic ;
using System.Data ;
using System.Data.Common ;
using System.Data.Sql ;
using System.Data.SqlClient ;
using System.Net ;
using System.Text ;
#if NETFRAMEWORK
using System.Data.Sql ;
#else
#endif
namespace Apewer.Source
{
/// <summary>用于快速连接 Microsoft SQL Server 数据库的辅助。</summary>
/// <summary></summary>
[Serializable]
public class SqlClin et : IDatabase
public class SqlClien t : IDbClient
{
#region 变量定义。
private SqlConnection _d b = null ;
#region 变量、构造函数
private Timeout _ timeout ;
private Timeout _ timeout = null ;
private string _ connectionstring = "" ;
private string _ address = "" ;
private string _ store = "" ;
private string _ user = "" ;
private string _ pass = "" ;
#endregion
/// <summary>获取或设置日志记录。</summary>
public Logger Logger { get ; set ; }
#region 构造函数。
/// <summary>创建空参数的数据库连接实例。</summary>
public SqlClinet ( )
{
_ timeout = Timeout . Default ;
}
/// <summary>超时设定。</summary>
public Timeout Timeout { get = > _ timeout ; }
/// <summary>使用连接字符串创建数据库连接实例。</summary>
public SqlClin et ( string connectionString )
public SqlClient ( string connectionString , Timeout timeout = null )
{
_ timeout = Timeout . Default ;
_ timeout = timeout ? ? Timeout . Default ;
_ connectionstring = connectionString ? ? "" ;
}
/// <summary>使用连接凭据创建数据库连接实例。</summary>
/// <param name="address">服务器地址。</param>
/// <param name="store">数据库名称。</param>
public SqlClinet ( string address , string store )
{
_ timeout = Timeout . Default ;
_ address = address ? ? "" ;
_ store = store ? ? "" ;
UpdateConnectString ( ) ;
}
public SqlClient ( string address , string store , string user , string pass , Timeout timeout = null )
{
if ( timeout = = null ) timeout = Timeout . Default ;
/// <summary>使用连接凭据创建数据库连接实例。</summary>
/// <param name="address">服务器地址。</param>
/// <param name="store">数据库名称。</param>
/// <param name="user">用户名。</param>
/// <param name="pass">密码。</param>
public SqlClinet ( string address , string store , string user , string pass )
{
_ timeout = Timeout . Default ;
_ address = address ? ? "" ;
_ store = store ? ? "" ;
_ user = user ? ? "" ;
_ pass = pass ? ? "" ;
UpdateConnectString ( ) ;
var a = TextUtility . AntiInject ( address ) ;
var s = TextUtility . AntiInject ( store ) ;
var u = TextUtility . AntiInject ( user ) ;
var p = TextUtility . AntiInject ( pass ) ;
var cs = $"data source = {a}; initial catalog = {s}; " ;
if ( string . IsNullOrEmpty ( u ) ) cs + = "integrated security = sspi; " ;
else
{
cs + = $"user id = {u}; " ;
if ( ! string . IsNullOrEmpty ( p ) ) cs + = $"password = {p}; " ;
}
cs + = $"connection timeout = {timeout.Connect}; " ;
_ timeout = timeout ? ? Timeout . Default ;
_ connectionstring = cs ;
}
#endregion
#region 日志。
/// <summary>获取或设置日志记录。</summary>
public Logger Logger { get ; set ; }
#region Ado - Connection
private void LogError ( string action , Exception ex , string addtion )
{
var logger = Logger ;
if ( logger ! = null ) logger . Error ( this , "SQL Server" , action , ex . GetType ( ) . FullName , ex . Message , addtion ) ;
}
private SqlConnection _d b = null ;
#endregion
/// <summary>连接字符串。</summary>
public string ConnectionString { get = > _ connectionstring ; }
#region 实现接口。
/// <summary>获取当前的 SqlConnection 对象。</summary>
public IDbConnection Connection { get = > _d b ; }
/// <summary>数据库是否已经连接。</summary>
public bool Online
@ -107,7 +91,7 @@ namespace Apewer.Source
if ( _d b = = null )
{
_d b = new SqlConnection ( ) ;
_d b . ConnectionString = ConnectionS tring;
_d b . ConnectionString = _ connections tring;
}
else
{
@ -124,7 +108,7 @@ namespace Apewer.Source
}
catch ( Exception ex )
{
LogError ( "Connection" , ex , _d b . ConnectionString ) ;
Logger . Error ( nameof ( SqlClient ) , "Connection" , ex , _d b . ConnectionString ) ;
Close ( ) ;
return false ;
}
@ -135,6 +119,11 @@ namespace Apewer.Source
{
if ( _d b ! = null )
{
if ( _ transaction ! = null )
{
if ( _ autocommit ) Commit ( ) ;
else Rollback ( ) ;
}
_d b . Close ( ) ;
_d b . Dispose ( ) ;
_d b = null ;
@ -142,16 +131,80 @@ namespace Apewer.Source
}
/// <summary>关闭连接,释放对象所占用的系统资源,并清除连接信息。</summary>
public void Dispose ( )
{
Close ( ) ;
_ connectionstring = "" ;
_ address = "" ;
_ store = "" ;
_ user = "" ;
_ pass = "" ;
public void Dispose ( ) = > Close ( ) ;
#endregion
#region Ado - Transaction
private IDbTransaction _ transaction = null ;
private bool _ autocommit = false ;
/// <summary>启动事务。</summary>
public string Begin ( bool commit = true ) = > Begin ( commit , null ) ;
/// <summary>启动事务。</summary>
public string Begin ( bool commit , Class < IsolationLevel > isolation )
{
if ( ! Connect ( ) ) return "未连接。" ;
if ( _ transaction ! = null ) return "存在已启动的事务,无法再次启动。" ;
try
{
_ transaction = isolation ? _d b . BeginTransaction ( isolation . Value ) : _d b . BeginTransaction ( ) ;
_ autocommit = commit ;
return null ;
}
catch ( Exception ex )
{
Logger . Error ( nameof ( SqlClient ) , "Begin" , ex . Message ( ) ) ;
return ex . Message ( ) ;
}
}
/// <summary>提交事务。</summary>
public string Commit ( )
{
if ( _ transaction = = null ) return "事务不存在。" ;
try
{
_ transaction . Commit ( ) ;
RuntimeUtility . Dispose ( _ transaction ) ;
_ transaction = null ;
return null ;
}
catch ( Exception ex )
{
RuntimeUtility . Dispose ( _ transaction ) ;
_ transaction = null ;
Logger . Error ( nameof ( SqlClient ) , "Commit" , ex . Message ( ) ) ;
return ex . Message ( ) ;
}
}
/// <summary>从挂起状态回滚事务。</summary>
public string Rollback ( )
{
if ( _ transaction = = null ) return "事务不存在。" ;
try
{
_ transaction . Rollback ( ) ;
RuntimeUtility . Dispose ( _ transaction ) ;
_ transaction = null ;
return null ;
}
catch ( Exception ex )
{
RuntimeUtility . Dispose ( _ transaction ) ;
_ transaction = null ;
Logger . Error ( nameof ( SqlClient ) , "Rollback" , ex . Message ) ;
return ex . Message ( ) ;
}
}
#endregion
#region Ado - SQL
/// <summary>查询。</summary>
public IQuery Query ( string sql ) = > Query ( sql , null ) ;
@ -159,44 +212,40 @@ namespace Apewer.Source
public IQuery Query ( string sql , IEnumerable < IDataParameter > parameters )
{
if ( TextUtility . IsBlank ( sql ) ) return Example . InvalidQueryStatement ;
const string tablename = "queryresult" ;
var connected = Connect ( ) ;
if ( ! connected ) return Example . InvalidQueryConnection ;
var query = new Query ( ) ;
try
{
var command = new SqlCommand ( ) ;
command . Connection = _d b ;
command . CommandTimeout = Timeout . Query ;
command . CommandText = sql ;
if ( parameters ! = null )
using ( var command = new SqlCommand ( ) )
{
foreach ( var parameter in parameters )
command . Connection = _d b ;
command . CommandTimeout = _ timeout . Query ;
command . CommandText = sql ;
if ( parameters ! = null )
{
if ( parameter ! = null ) command . Parameters . Add ( parameter ) ;
foreach ( var parameter in parameters )
{
if ( parameter ! = null ) command . Parameters . Add ( parameter ) ;
}
}
}
using ( var dataset = new DataSet ( ) )
{
using ( var dataadapter = new SqlDataAdapter ( sql , _d b ) )
using ( var ds = new DataSet ( ) )
{
dataadapter . Fill ( dataset , tablename ) ;
query . Table = dataset . Tables [ tablename ] ;
using ( var da = new SqlDataAdapter ( sql , _d b ) )
{
const string name = "resule" ;
da . Fill ( ds , name ) ;
var table = ds . Tables [ name ] ;
return new Query ( table , true ) ;
}
}
}
command . Dispose ( ) ;
query . Success = true ;
}
catch ( Exception exception )
{
LogError ( "Query" , exception , sql ) ;
query . Success = false ;
query . Exception = exception ;
Logger . Error ( nameof ( SqlClient ) , "Query" , exception , sql ) ;
return new Query ( exception ) ;
}
return query ;
}
/// <summary>执行。</summary>
@ -210,119 +259,42 @@ namespace Apewer.Source
var connected = Connect ( ) ;
if ( ! connected ) return Example . InvalidExecuteConnection ;
var transaction = _d b . BeginTransaction ( ) ;
var execute = new Execute ( ) ;
var inTransaction = _ transaction ! = null ;
if ( ! inTransaction ) Begin ( ) ;
try
{
var command = new SqlCommand ( ) ;
command . Connection = _d b ;
command . Transaction = transaction ;
command . CommandTimeout = Timeout . Execute ;
command . CommandText = sql ;
if ( parameters ! = null )
using ( var command = new SqlCommand ( ) )
{
foreach ( var parameter in parameters )
command . Connection = _d b ;
command . Transaction = ( SqlTransaction ) _ transaction ;
command . CommandTimeout = _ timeout . Execute ;
command . CommandText = sql ;
if ( parameters ! = null )
{
if ( parameter ! = null ) command . Parameters . Add ( parameter ) ;
foreach ( var parameter in parameters )
{
if ( parameter ! = null ) command . Parameters . Add ( parameter ) ;
}
}
var rows = command . ExecuteNonQuery ( ) ;
if ( ! inTransaction ) Commit ( ) ; // todo 此处应该检查事务提交产生的错误。
return new Execute ( true , rows ) ;
}
execute . Rows + = command . ExecuteNonQuery ( ) ;
transaction . Commit ( ) ;
command . Dispose ( ) ;
execute . Success = true ;
}
catch ( Exception exception )
{
try { transaction . Rollback ( ) ; } catch { }
LogError ( "Execute" , exception , sql ) ;
execute . Success = false ;
execute . Exception = exception ;
Logger . Error ( nameof ( SqlClient ) , "Execute" , exception , sql ) ;
if ( ! inTransaction ) Rollback ( ) ;
return new Execute ( exception ) ;
}
try { transaction . Dispose ( ) ; } catch { }
return execute ;
}
#endregion
#region 属性。
/// <summary>获取当前的 SqlConnection 对象。</summary>
public SqlConnection Connection
{
get { return _d b ; }
}
/// <summary>获取或设置连接字符串。</summary>
public string ConnectionString
{
get { return _ connectionstring ; }
set { _ connectionstring = value ? ? "" ; _ address = "" ; _ store = "" ; _ user = "" ; _ pass = "" ; }
}
/// <summary>获取或设置数据库服务器的地址。</summary>
public string Address
{
get { return _ address ; }
set { _ address = value ? ? "" ; UpdateConnectString ( ) ; }
}
/// <summary>获取或设置数据库名称。</summary>
public string Store
{
get { return _ store ; }
set { _ store = value ? ? "" ; UpdateConnectString ( ) ; }
}
/// <summary>获取或设置用于连接数据库服务器的用户名,为空则使用 Windows 用户登录。</summary>
public string User
{
get { return _ user ; }
set { _ user = value ? ? "" ; UpdateConnectString ( ) ; }
}
/// <summary>获取或设置用于连接数据库服务器的密码。</summary>
public string Pass
{
get { return _ pass ; }
set { _ pass = value ? ? "" ; UpdateConnectString ( ) ; }
}
/// <summary>获取或设置超时。</summary>
public Timeout Timeout
{
get { return _ timeout ; }
set { _ timeout = value ; }
}
#endregion
#region 方法。
/// <summary>指定连接凭据后,是否符合连接要求。</summary>
public bool Proven ( )
{
return Proven ( _ address , _ store , _ user , _ pass ) ;
}
private void UpdateConnectString ( )
{
_ connectionstring = "" ;
_ connectionstring + = "data source = " + _ address + "; " ;
_ connectionstring + = "initial catalog = " + _ store + "; " ;
if ( string . IsNullOrEmpty ( User ) )
{
_ connectionstring + = "integrated security = sspi; " ;
}
else
{
_ connectionstring + = "user id = " + _ user + "; " ;
if ( ! string . IsNullOrEmpty ( _ pass ) ) _ connectionstring + = "password = " + _ pass + "; " ;
}
_ connectionstring + = "connection timeout = " + Timeout . Connect . ToString ( ) + ";" ;
}
#region ORM
/// <summary>查询数据库中的所有表名。</summary>
public List < string > TableNames ( )
public string [ ] TableNames ( )
{
var list = new List < string > ( ) ;
if ( Connect ( ) )
@ -337,11 +309,11 @@ namespace Apewer.Source
}
query . Dispose ( ) ;
}
return list ;
return list . ToArray ( ) ;
}
/// <summary>查询数据库实例中的所有数据库名。</summary>
public List < string > StoreNames ( )
public string [ ] StoreNames ( )
{
var list = new List < string > ( ) ;
if ( Connect ( ) )
@ -360,11 +332,11 @@ namespace Apewer.Source
}
query . Dispose ( ) ;
}
return list ;
return list . ToArray ( ) ;
}
/// <summary>查询表中的所有列名。</summary>
public List < string > ColumnNames ( string tableName )
public string [ ] ColumnNames ( string tableName )
{
var list = new List < string > ( ) ;
if ( Connect ( ) )
@ -380,21 +352,17 @@ namespace Apewer.Source
}
query . Dispose ( ) ;
}
return list ;
return list . ToArray ( ) ;
}
/// <summary>创建表,当表不存在时创建表,当现存表中缺少模型中属性对应的列时增加列。成功时返回空字符串,发生异常时返回异常信息。</summary>
public string Initialize < T > ( ) where T : class , IRecord , new ( ) = > Initialize ( typeof ( T ) ) ;
/// <summary>创建表,当表不存在时创建表,当现存表中缺少模型中属性对应的列时增加列。成功时返回空字符串,发生异常时返回异常信息。</summary>
public string Initialize ( Record model ) = > model = = null ? "参数无效。" : Initialize ( model ) ;
/// <summary>创建表,当表不存在时创建表,当现存表中缺少模型中属性对应的列时增加列。成功时返回空字符串,发生异常时返回异常信息。</summary>
public string Initialize ( Type model )
{
var structure = null as TableStructure ;
try { structure = TableStructure . ParseModel ( model ) ; }
catch ( Exception exception ) { return exception . Message ; }
var structure = TableStructure . Parse ( model ) ;
if ( structure = = null ) return "无法解析记录模型。" ;
// 连接数据库。
if ( ! Connect ( ) ) return "连接数据库失败。" ;
@ -402,9 +370,9 @@ namespace Apewer.Source
// 检查现存表。
var exists = false ;
var tables = TableNames ( ) ;
if ( tables . Count > 0 )
if ( tables . Length > 0 )
{
var lower = structure . Tabl e. ToLower ( ) ;
var lower = structure . Nam e. ToLower ( ) ;
foreach ( var table in tables )
{
if ( TextUtility . IsBlank ( table ) ) continue ;
@ -419,8 +387,8 @@ namespace Apewer.Source
if ( exists )
{
// 获取已存在的列名。
var columns = ColumnNames ( structure . Tabl e) ;
if ( columns . Count > 0 )
var columns = ColumnNames ( structure . Nam e) ;
if ( columns . Length > 0 )
{
var lower = new List < string > ( ) ;
foreach ( var column in columns )
@ -428,11 +396,11 @@ namespace Apewer.Source
if ( TextUtility . IsBlank ( column ) ) continue ;
lower . Add ( column . ToLower ( ) ) ;
}
columns = lower ;
columns = lower . ToArray ( ) ;
}
// 增加列。
foreach ( var column in structure . Columns . Values )
foreach ( var column in structure . Columns )
{
// 检查 Independent 特性。
if ( structure . Independent & & column . Independent ) continue ;
@ -444,100 +412,83 @@ namespace Apewer.Source
var type = GetColumnDeclaration ( column ) ;
if ( type = = TextUtility . Empty ) return TextUtility . Merge ( "类型 " , column . Type . ToString ( ) , " 不受支持。" ) ;
var sql = TextUtility . Merge ( "alter table [" , structure . Tabl e, "] add " , type , "; " ) ;
var sql = TextUtility . Merge ( "alter table [" , structure . Nam e, "] add " , type , "; " ) ;
var execute = Execute ( sql ) ;
if ( execute . Success = = false ) return execute . Error ;
if ( execute . Success = = false ) return execute . Message ;
}
return TextUtility . Empty ;
}
else
{
var sqlcolumns = new List < string > ( ) ;
foreach ( var kvp in structure . Columns )
foreach ( var column in structure . Columns )
{
var property = kvp . Key ;
var column = kvp . Value ;
// 检查 Independent 特性。
if ( structure . Independent & & column . Independent ) continue ;
var type = GetColumnDeclaration ( column ) ;
if ( ! column . Independent & & p roperty = = "Key" ) type = type + " primary key" ;
if ( ! column . Independent & & column . P roperty. Name = = "Key" ) type = type + " primary key" ;
if ( type = = TextUtility . Empty ) return TextUtility . Merge ( "类型 " , column . Type . ToString ( ) , " 不受支持。" ) ;
sqlcolumns . Add ( type ) ;
}
var sql = TextUtility . Merge ( "create table [" , structure . Tabl e, "](" , string . Join ( ", " , sqlcolumns . ToArray ( ) ) , "); " ) ;
var sql = TextUtility . Merge ( "create table [" , structure . Nam e, "](" , string . Join ( ", " , sqlcolumns . ToArray ( ) ) , "); " ) ;
var execute = Execute ( sql ) ;
if ( execute . Success ) return TextUtility . Empty ;
return execute . Error ;
return execute . Message ;
}
}
/// <summary>插入记录。成功时候返回空字符串,发生异常时返回异常 信息。</summary>
/// <summary>插入记录。返回错误 信息。</summary>
public string Insert ( IRecord record )
{
if ( record = = null ) return "参数无效。" ;
var type = record . GetType ( ) ;
record . FixProperties ( ) ;
var structure = null as TableStructure ;
try { structure = TableStructure . ParseModel ( record ) ; }
catch ( Exception exception ) { return exception . Message ; }
var parameters = structure . CreateDataParameters ( record , CreateDataParameter ) ;
var sql = GenerateInsertStatement ( structure . Table , parameters ) ;
var structure = TableStructure . Parse ( record . GetType ( ) ) ;
if ( structure = = null ) return "无法解析记录模型。" ;
var parameters = structure . CreateParameters ( record , CreateDataParameter ) ;
var sql = GenerateInsertStatement ( structure . Name , parameters ) ;
var execute = Execute ( sql , parameters ) ;
if ( execute . Success ) return TextUtility . Empty ;
return execute . Error ;
return execute . Message ;
}
/// <summary>
/// <para>更新记录,实体中的 Created 和 Key 属性不被更新。成功时返回空字符串,发生异常时返回异常信息。</para>
/// <para>无法更新拥有 Independent 特性的模型。</para>
/// </summary>
/// <summary>更新记录,实体中的 Key 属性不被更新。返回错误信息。</summary>
/// <remarks>无法更新带有 Independent 特性的模型(缺少 Key 属性)。</remarks>
public string Update ( IRecord record )
{
if ( record = = null ) return "参数无效。" ;
var type = record . GetType ( ) ;
record . FixProperties ( ) ;
record . SetUpdated ( ) ;
var structure = null as TableStructure ;
try { structure = TableStructure . ParseModel ( record ) ; }
catch ( Exception exception ) { return exception . Message ; }
// 检查 Independent 特性。
if ( structure . Independent ) return "无法更新拥有 Independent 特性的模型。" ;
var parameters = structure . CreateDataParameters ( record , CreateDataParameter , "_created" , "_key" ) ;
var sql = GenerateUpdateStatement ( structure . Table , record . Key , parameters ) ;
var structure = TableStructure . Parse ( record . GetType ( ) ) ;
if ( structure = = null ) return "无法解析记录模型。" ;
if ( structure . Independent ) return "无法更新带有 Independent 特性的模型。" ;
var parameters = structure . CreateParameters ( record , CreateDataParameter , "_key" ) ;
var sql = GenerateUpdateStatement ( structure . Name , record . Key , parameters ) ;
var execute = Execute ( sql , parameters ) ;
if ( execute . Success ) return TextUtility . Empty ;
return execute . Error ;
return execute . Message ;
}
/// <summary>获取按指定语句查询到的所有记录。</summary>
public Result < List < IRecord > > Query ( Type model , string sql ) = > OrmHelper . Query ( this , model , sql ) ;
public Result < IRecord [ ] > Query ( Type model , string sql ) = > OrmHelper . Query ( this , model , sql ) ;
/// <summary>获取按指定语句查询到的所有记录。</summary>
public Result < List < T > > Query < T > ( string sql ) where T : class , IRecord , new ( ) = > OrmHelper . Query < T > ( this , sql ) ;
public Result < T [ ] > Query < T > ( string sql ) where T : class , IRecord , new ( ) = > OrmHelper . Query < T > ( this , sql ) ;
/// <summary>获取记录。</summary>
public Result < List < IRecord > > Query ( Type model , long flag = 0 ) = > OrmHelper . Query ( this , model , ( tn ) = >
public Result < IRecord [ ] > Query ( Type model , long flag = 0 ) = > OrmHelper . Query ( this , model , ( tn ) = >
{
if ( flag = = 0 ) return $"select * from [{tn}]; " ;
return $"select * from [{tn}] where _flag={flag}; " ;
} ) ;
/// <summary>获取记录。</summary>
public Result < List < T > > Query < T > ( long flag = 0 ) where T : class , IRecord , new ( ) = > OrmHelper . Query < T > ( this , ( tn ) = >
public Result < T [ ] > Query < T > ( long flag = 0 ) where T : class , IRecord , new ( ) = > OrmHelper . Query < T > ( this , ( tn ) = >
{
if ( flag = = 0 ) return $"select * from [{tn}]; " ;
return $"select * from [{tn}] where _flag={flag}; " ;
@ -558,66 +509,55 @@ namespace Apewer.Source
} ) ;
/// <summary>查询有效的 Key 值。</summary>
public Result < List < string > > Keys ( Type model , long flag = 0 ) = > OrmHelper . Keys ( this , model , ( tn ) = >
public Result < string [ ] > Keys ( Type model , long flag = 0 ) = > OrmHelper . Keys ( this , model , ( tn ) = >
{
if ( flag = = 0 ) return $"select _key from [{tn}]; " ;
return $"select _key from [{tn}] where _flag={flag}; " ;
} ) ;
/// <summary>查询有效的 Key 值。</summary>
public Result < List < string > > Keys < T > ( long flag = 0 ) where T : class , IRecord , new ( ) = > Keys ( typeof ( T ) , flag ) ;
public Result < string [ ] > Keys < T > ( long flag = 0 ) where T : class , IRecord , new ( ) = > Keys ( typeof ( T ) , flag ) ;
#endregion
#region 静态方法。
#region public static
#if NETFRAMEWORK
private static string GetColumnDeclaration ( ColumnAttribute column )
/// <summary>枚举本地网络中服务器的名称。</summary>
public static SqlServerSource [ ] EnumerateServer ( )
{
var type = TextUtility . Empty ;
var vcolumn = column ;
var length = Math . Max ( 0 , vcolumn . Length ) ;
switch ( vcolumn . Type )
var list = new List < SqlServerSource > ( ) ;
// 表中列名:ServerName、InstanceName、IsClustered、Version。
using ( var query = new Query ( SqlDataSourceEnumerator . Instance . GetDataSources ( ) ) )
{
case ColumnType . Integer :
type = "bigint" ;
break ;
case ColumnType . Float :
type = "float" ;
break ;
case ColumnType . Bytes :
type = "image" ;
break ;
case ColumnType . DateTime :
type = "datetime" ;
break ;
case ColumnType . VarChar :
type = TextUtility . Merge ( "varchar(" , Math . Min ( 8 0 0 0 , length ) . ToString ( ) , ")" ) ;
break ;
case ColumnType . VarChar255 :
type = TextUtility . Merge ( "varchar(255)" ) ;
break ;
case ColumnType . VarCharMax :
type = TextUtility . Merge ( "varchar(max)" ) ;
break ;
case ColumnType . Text :
type = TextUtility . Merge ( "text" ) ;
break ;
case ColumnType . NVarChar :
type = TextUtility . Merge ( "nvarchar(" , Math . Min ( 4 0 0 0 , length ) . ToString ( ) , ")" ) ;
break ;
case ColumnType . NVarChar255 :
type = TextUtility . Merge ( "nvarchar(255)" ) ;
break ;
case ColumnType . NVarCharMax :
type = TextUtility . Merge ( "nvarchar(max)" ) ;
break ;
case ColumnType . NText :
type = TextUtility . Merge ( "ntext" ) ;
break ;
default :
return TextUtility . Empty ;
for ( int i = 0 ; i < query . Rows ; i + + )
{
var item = new SqlServerSource ( ) ;
item . ServerName = query . Text ( i , "ServerName" ) ;
list . Add ( item ) ;
}
}
return TextUtility . Merge ( "[" , vcolumn . Field , "] " , type ) ;
return list . ToArray ( ) ;
}
#endif
/// <summary>指定的连接凭据是否符合连接要求,默认指定 master 数据库。</summary>
public static bool Proven ( string address , string user , string pass ) = > Proven ( address , "master" , user , pass ) ;
/// <summary>指定的连接凭据是否符合连接要求。</summary>
public static bool Proven ( string address , string store , string user , string pass )
{
var a = string . IsNullOrEmpty ( address ) ;
var s = string . IsNullOrEmpty ( store ) ;
var u = string . IsNullOrEmpty ( user ) ;
var p = string . IsNullOrEmpty ( pass ) ;
if ( a ) return false ;
if ( s ) return false ;
if ( u & & ! p ) return false ;
return true ;
}
/// <summary>创建参数。</summary>
@ -651,12 +591,12 @@ namespace Apewer.Source
vtype = SqlDbType . DateTime ;
break ;
case ColumnType . VarChar :
case ColumnType . VarChar255 :
case ColumnType . VarChar191 :
case ColumnType . VarCharMax :
vtype = SqlDbType . VarChar ;
break ;
case ColumnType . NVarChar :
case ColumnType . NVarChar255 :
case ColumnType . NVarChar191 :
case ColumnType . NVarCharMax :
vtype = SqlDbType . VarChar ;
break ;
@ -679,9 +619,9 @@ namespace Apewer.Source
case ColumnType . NVarChar :
vsize = NumberUtility . Restrict ( vsize , 0 , 4 0 0 0 ) ;
break ;
case ColumnType . VarChar255 :
case ColumnType . NVarChar255 :
vsize = NumberUtility . Restrict ( vsize , 0 , 2 5 5 ) ;
case ColumnType . VarChar191 :
case ColumnType . NVarChar191 :
vsize = NumberUtility . Restrict ( vsize , 0 , 1 9 1 ) ;
break ;
default :
vsize = 0 ;
@ -728,51 +668,60 @@ namespace Apewer.Source
return p ;
}
///// <summary>枚举本地网络中服务器的名称。</summary>
//public static List<string> EnumerateServer()
//{
// // 表中列名:ServerName、InstanceName、IsClustered、Version。
// var table = SqlDataSourceEnumerator.Instance.GetDataSources();
// var query = new Query();
// query.Success = table != null;
// query.Table = table;
// var list = new List<string>();
// for (int i = 0; i < query.Rows; i++)
// {
// var sn = query.Text(i, "ServerName");
// if (!string.IsNullOrEmpty(sn)) list.Add(sn);
// }
// query.Dispose();
// return list;
//}
/// <summary>指定的连接凭据是否符合连接要求。</summary>
public static bool Proven ( SqlClinet sqlserver )
{
return Proven ( sqlserver . _ address , sqlserver . _ store , sqlserver . _ user , sqlserver . _ pass ) ;
}
#endregion
/// <summary>指定的连接凭据是否符合连接要求,默认指定 master 数据库。</summary>
public static bool Proven ( string address , string user , string pass ) = > Proven ( address , "master" , user , pass ) ;
#region private
/// <summary>指定的连接凭据是否符合连接要求。</summary>
public static bool Proven ( string address , string store , string user , string pass )
static string GetColumnDeclaration ( ColumnAttribute column )
{
var a = string . IsNullOrEmpty ( address ) ;
var s = string . IsNullOrEmpty ( store ) ;
var u = string . IsNullOrEmpty ( user ) ;
var p = string . IsNullOrEmpty ( pass ) ;
if ( a ) return false ;
if ( s ) return false ;
if ( u & & ! p ) return false ;
return true ;
var type = TextUtility . Empty ;
var vcolumn = column ;
var length = Math . Max ( 0 , vcolumn . Length ) ;
switch ( vcolumn . Type )
{
case ColumnType . Integer :
type = "bigint" ;
break ;
case ColumnType . Float :
type = "float" ;
break ;
case ColumnType . Bytes :
type = "image" ;
break ;
case ColumnType . DateTime :
type = "datetime" ;
break ;
case ColumnType . VarChar :
type = TextUtility . Merge ( "varchar(" , Math . Min ( 8 0 0 0 , length ) . ToString ( ) , ")" ) ;
break ;
case ColumnType . VarChar191 :
type = TextUtility . Merge ( "varchar(191)" ) ;
break ;
case ColumnType . VarCharMax :
type = TextUtility . Merge ( "varchar(max)" ) ;
break ;
case ColumnType . Text :
type = TextUtility . Merge ( "text" ) ;
break ;
case ColumnType . NVarChar :
type = TextUtility . Merge ( "nvarchar(" , Math . Min ( 4 0 0 0 , length ) . ToString ( ) , ")" ) ;
break ;
case ColumnType . NVarChar191 :
type = TextUtility . Merge ( "nvarchar(255)" ) ;
break ;
case ColumnType . NVarCharMax :
type = TextUtility . Merge ( "nvarchar(max)" ) ;
break ;
case ColumnType . NText :
type = TextUtility . Merge ( "ntext" ) ;
break ;
default :
return TextUtility . Empty ;
}
return TextUtility . Merge ( "[" , vcolumn . Field , "] " , type ) ;
}
#endregion
#region Linq Utility
private static string GetParameterName ( string parameter )
static string GetParameterName ( string parameter )
{
var name = TextUtility . AntiInject ( parameter , 2 5 5 ) ;
if ( name . StartsWith ( "@" ) & & name . Length > 1 )
@ -782,7 +731,7 @@ namespace Apewer.Source
return name ;
}
private static string GetParameterName ( IDataParameter parameter )
static string GetParameterName ( IDataParameter parameter )
{
var name = TextUtility . Empty ;
if ( parameter ! = null )
@ -792,7 +741,7 @@ namespace Apewer.Source
return name ;
}
private static List < string > GetParametersNames ( IEnumerable < IDataParameter > parameters )
static string [ ] GetParametersNames ( IEnumerable < IDataParameter > parameters )
{
var columns = new List < string > ( ) ;
if ( parameters ! = null )
@ -805,10 +754,10 @@ namespace Apewer.Source
columns . Add ( name ) ;
}
}
return columns ;
return columns . ToArray ( ) ;
}
private static string GenerateInsertStatement ( string table , List < string > columns )
static string GenerateInsertStatement ( string table , string [ ] columns )
{
var result = TextUtility . Empty ;
var vtable = TextUtility . AntiInject ( table , 2 5 5 ) ;
@ -835,7 +784,7 @@ namespace Apewer.Source
return result ;
}
private static string GenerateUpdateStatement ( string table , string key , List < string > columns )
static string GenerateUpdateStatement ( string table , string key , string [ ] columns )
{
var result = TextUtility . Empty ;
var vtable = TextUtility . AntiInject ( table , 2 5 5 ) ;
@ -858,14 +807,14 @@ namespace Apewer.Source
/// <summary>生成 INSERT INTO 语句。表名必须有效,无有效参数时将获取空结果。</summary>
/// <exception cref="System.ArgumentException"></exception>
/// <exception cref="System.ArgumentNullException"></exception>
private static string GenerateInsertStatement ( string table , IEnumerable < IDataParameter > parameters )
static string GenerateInsertStatement ( string table , IEnumerable < IDataParameter > parameters )
{
if ( table = = null ) throw new ArgumentNullException ( nameof ( table ) ) ;
var tableName = TextUtility . AntiInject ( table , 2 5 5 ) ;
if ( TextUtility . IsBlank ( tableName ) ) throw new ArgumentException ( "表名无效。" , nameof ( table ) ) ;
var vcolumns = GetParametersNames ( parameters ) ;
if ( vcolumns . Count < 1 ) return TextUtility . Empty ;
if ( vcolumns . Length < 1 ) return TextUtility . Empty ;
return GenerateInsertStatement ( tableName , vcolumns ) ;
}
@ -873,7 +822,7 @@ namespace Apewer.Source
/// <summary>生成 UPDATE 语句,键字段名为“_key”。表名必须有效,键值必须有效,无有效参数时将获取空结果。</summary>
/// <exception cref="System.ArgumentException"></exception>
/// <exception cref="System.ArgumentNullException"></exception>
private static string GenerateUpdateStatement ( string table , string key , IEnumerable < IDataParameter > parameters )
static string GenerateUpdateStatement ( string table , string key , IEnumerable < IDataParameter > parameters )
{
if ( table = = null ) throw new ArgumentNullException ( nameof ( table ) ) ;
var t = TextUtility . AntiInject ( table , 2 5 5 ) ;
@ -884,7 +833,7 @@ namespace Apewer.Source
if ( TextUtility . IsBlank ( k ) ) throw new ArgumentException ( "键值无效。" , nameof ( table ) ) ;
var columes = GetParametersNames ( parameters ) ;
if ( columes . Count < 1 ) return TextUtility . Empty ;
if ( columes . Length < 1 ) return TextUtility . Empty ;
return GenerateUpdateStatement ( t , k , columes ) ;
}
@ -894,5 +843,3 @@ namespace Apewer.Source
}
}
#endif