Maison  >  Article  >  base de données  >  C# SqlServer的Helper基类

C# SqlServer的Helper基类

WBOY
WBOYoriginal
2016-06-07 17:40:461363parcourir

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections; using System.Data; using System.Data.SqlClient; using System.Data.Common; namespace SqlServerDAL { public class SqlHelper { sta


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Data;
using System.Data.SqlClient;
using System.Data.Common;


namespace SqlServerDAL
{
public class SqlHelper
{
static string _SqlConnectionString;
public static string SqlConnectionString
{
get
{
return _SqlConnectionString;
}
set
{
_SqlConnectionString = value;
}
}


///


/// 设置参数内容
///

/// 名称
/// 数据类型
/// 长度大小
///
/// 类型
///
public static SqlParameter SetDataParameter(string ParamName, SqlDbType DbType, Int32 Size, object paramevalue, ParameterDirection Direction)
{
SqlParameter param = new SqlParameter();
param.SqlDbType = DbType;
param.ParameterName = ParamName;

if (Size > 0)
{
param.Size = Size;
}
if (paramevalue.ToString() != "" && paramevalue != null && Direction != ParameterDirection.Output)
{
param.Value = paramevalue;
}

param.Direction = Direction;
return param;
}
///
/// 设置参数内容
///

/// 名称
/// 数据类型
/// 类型
///
public static SqlParameter SetDataParameter(string ParamName, SqlDbType DbType, ParameterDirection Direction)
{
SqlParameter param = new SqlParameter();
param.SqlDbType = DbType;
param.ParameterName = ParamName;
param.Direction = Direction;
return param;
}

#region 私有办法
///
/// 将SqlParameter参数数组(参数值)分派给DbCommand号令.
/// 这个办法将给任何一个参数分派DBNull.Value;
/// 该操纵将阻拦默认值的应用.
///

/// 号令名
/// SqlParameters数组
private static void AttachParameters(SqlCommand command, SqlParameter[] commandParameters)
{
if (command == null) throw new ArgumentNullException("command");
if (commandParameters != null)
{
foreach (SqlParameter p in commandParameters)
{
if (p != null)
{
// 搜检未分派值的输出参数,将其分派以DBNull.Value.
if ((p.Direction == ParameterDirection.InputOutput || p.Direction == ParameterDirection.Input) &&
(p.Value == null))
{
p.Value = DBNull.Value;
}
command.Parameters.Add(p);
}
}
}
//应用完成后清除原所有参数值
// ClearIDataParameter();
}

///
/// 预处理惩罚用户供给的号令,数据库连接/事务/号令类型/参数
///

/// 一个有效的事务或者是null值
/// 号令类型 (存储过程,号令文本, 其它.)
/// 存储过程名或都SQL号令文本
/// 和号令相接洽关系的SqlParameter参数数组,若是没有参数为""null""
/// true 若是连接是打开的,则为true,其它景象下为false.
private static void PrepareCommand(SqlConnection Connection, SqlCommand Command, SqlTransaction transaction, CommandType commandType, string commandText, SqlParameter[] commandParameters, out bool mustCloseConnection)
{
try
{
if (Command == null) throw new ArgumentNullException("command");
if (commandText == null || commandText.Length == 0) throw new ArgumentNullException("commandText");

if (Connection.State != ConnectionState.Open)
{
mustCloseConnection = true;
Connection.Open();
}
else
{
mustCloseConnection = false;
}

// 给号令分派一个数据库连接.
Command.Connection = Connection;

// 设置号令文本(存储过程名或SQL语句)
Command.CommandText = commandText;

// 分派事务
if (transaction != null)
{
if (transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
Command.Transaction = transaction;
}

// 设置号令类型.
Command.CommandType = commandType;

// 分派号令参数
if (commandParameters != null)
{
//SqlParameter[] dpitem =
AttachParameters(Command, commandParameters);
}
}
catch
{
mustCloseConnection = false;
}
}
#endregion

#region uteDataSet 数据表
///
/// 履行指定命据库连接字符串的号令,返回DataSet.
///

/// 存储过程名称或SQL语句
/// 返回一个包含成果集的DataSet
public static DataSet uteDataSet(string commandText)
{
return uteDataSet((SqlTransaction)null, commandText, CommandType.Text, (SqlParameter[])null);
}
///
/// 履行指定命据库连接字符串的号令,返回DataSet.
///

/// 存储过程名称或SQL语句
/// 号令类型 (存储过程,号令文本或其它)
/// 参数
/// 返回一个包含成果集的DataSet
public static DataSet uteDataSet(SqlTransaction transaction, string commandText, CommandType commandType, params SqlParameter[] commandParameters)
{
if (SqlConnectionString == null || SqlConnectionString.Length == 0) throw new ArgumentNullException("ConnectionString");

using (SqlConnection connection = new SqlConnection(SqlConnectionString))
{

connection.Open();
bool mustCloseConnection = false;
SqlCommand Command = new SqlCommand();
PrepareCommand(connection, Command, transaction, commandType, commandText, commandParameters, out mustCloseConnection);
try
{
SqlDataAdapter sdap = new SqlDataAdapter();
sdap.SelectCommand = Command;

DataSet ds = new DataSet();
sdap.Fill(ds);
Command.Parameters.Clear();//清空

Command.Dispose();
if (mustCloseConnection)
connection.Close();
return ds;
}
catch (Exception ex)
{
Command.Parameters.Clear();//清空

Command.Dispose();
if (mustCloseConnection)
connection.Close();

return new DataSet();
}
}
}
///
/// 履行指定命据库连接字符串的号令,返回DataSet.
///

/// 存储过程名称或SQL语句
/// 号令类型 (存储过程,号令文本或其它)
/// 返回一个包含成果集的DataSet
public static DataSet uteDataSet(string commandText, CommandType commandTytpe)
{
return uteDataSet((SqlTransaction)null, commandText, commandTytpe, (SqlParameter[])null);
}
///
/// 履行指定命据库连接字符串的号令,返回DataSet.
///

/// 输出输出参数成果凑集,例:{Name,Value}
/// 存储过程名称或SQL语句
/// 号令类型 (存储过程,号令文本或其它)
/// 参数
/// 返回一个包含成果集的DataSet
public static DataSet uteDataSet(ref Hashtable outParameters, string commandText, CommandType commandType, params SqlParameter[] commandParameters)
{
if (SqlConnectionString == null || SqlConnectionString.Length == 0) throw new ArgumentNullException("ConnectionString");

using (SqlConnection connection = new SqlConnection(SqlConnectionString))
{

connection.Open();

bool mustCloseConnection = false;
SqlCommand Command = new SqlCommand();
PrepareCommand(connection, Command, (SqlTransaction)null, commandType, commandText, commandParameters, out mustCloseConnection);
try
{
SqlDataAdapter sdap = new SqlDataAdapter();
sdap.SelectCommand = Command;

DataSet ds = new DataSet();
sdap.Fill(ds);

if (outParameters != null)
{
for (int i = 0; i {
if (Command.Parameters[i].Direction == ParameterDirection.Output)
{
if (!outParameters.Contains(Command.Parameters[i].ParameterName))
{
outParameters.Add(Command.Parameters[i].ParameterName, Command.Parameters[i].Value.ToString());
}
}
}
}
Command.Parameters.Clear();//清空

Command.Dispose();
if (mustCloseConnection)
connection.Close();
return ds;
}
catch (Exception ex)
{
Command.Parameters.Clear();//清空

Command.Dispose();
if (mustCloseConnection)
connection.Close();

return new DataSet();
}
}
}
///
/// 履行指定命据库连接字符串的号令,返回DataSet.
///

/// 输出输出参数成果凑集,例:{Name,Value}
/// 存储过程
/// 参数
/// 返回一个包含成果集的DataSet
public static DataSet uteDataSet(ref Hashtable outParameters, string SqlSPro, params SqlParameter[] commandParameters)
{
return uteDataSet(ref outParameters, SqlSPro, CommandType.StoredProcedure, commandParameters);
}
///
/// 履行指定命据库连接字符串的号令,返回DataSet.
///

/// 输出输出参数成果凑集,例:{Name,Value}
/// 存储过程
/// 参数
/// 返回一个包含成果集的DataSet
public static DataSet uteDataSet(string SqlSPro, params SqlParameter[] commandParameters)
{
Hashtable outParameters = null;
return uteDataSet(ref outParameters, SqlSPro, CommandType.StoredProcedure, commandParameters);
}
#endregion

#region uteScalar 返回成果集中的第一行第一列

///
/// 返回一条数据
///

///
///
///
///
///
public static object uteScalar(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
{
if (SqlConnectionString == null || SqlConnectionString.Length == 0) throw new ArgumentNullException("ConnectionString");

using (SqlConnection connection = new SqlConnection(SqlConnectionString))
{

connection.Open();
bool mustCloseConnection = false;
SqlCommand Command = new SqlCommand();
try
{
PrepareCommand(connection, Command, transaction, commandType, commandText, commandParameters, out mustCloseConnection);
object rvalue = Command.uteScalar();
Command.Parameters.Clear();//清空
Command.Dispose();
if (mustCloseConnection)
connection.Close();
return rvalue;
}
catch (Exception ex)
{
Command.Parameters.Clear();//清空
if (mustCloseConnection)
connection.Close();

return null;
}

}
}
///
/// 返回一条数据
///

///
///
///
public static object uteScalar(CommandType commandType, string commandText)
{
return uteScalar((SqlTransaction)null, commandType, commandText, (SqlParameter[])null);
}
///
/// 返回一条数据
///

///
///
///
public static object uteScalar(CommandType commandType, string commandText, params SqlParameter[] commandParameters)
{
return uteScalar((SqlTransaction)null, commandType, commandText, commandParameters);
}
///
/// 返回一条数据
///

///
///
///
///
public static object uteScalar(CommandType commandType, string commandText, SqlTransaction transaction)
{
return uteScalar(transaction, commandType, commandText, (SqlParameter[])null);
}
///
/// 返回一第数据
///

///
///
public static object uteScalar(string commandText)
{
return uteScalar(CommandType.Text, commandText, (SqlTransaction)null);
}
#endregion

#region uteDataReader 数据浏览器

public static DbDataReader uteDataReader(SqlConnection connection, SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
{
if (connection == null) throw new ArgumentNullException("connection");
DbDataReader reader = null;
bool mustCloseConnection = false;
SqlCommand Command = new SqlCommand();
try
{
PrepareCommand(connection, Command, transaction, commandType, commandText, commandParameters, out mustCloseConnection);

reader = Command.uteReader(System.Data.CommandBehavior.CloseConnection);

//reader = Command.uteReader(System.Data.CommandBehavior.CloseConnection);

Command.Parameters.Clear();//清空
//Command.Dispose();
}
catch (Exception ex)
{

}
return reader;
}
public static DbDataReader uteDataReader(SqlTransaction transaction, CommandType commandType, string commandText)
{
if (SqlConnectionString == null || SqlConnectionString.Length == 0) throw new ArgumentNullException("ConnectionString");
SqlConnection connection = null;
try
{
connection = new SqlConnection(SqlConnectionString);

connection.Open();
return uteDataReader(connection, transaction, commandType, commandText, (SqlParameter[])null);
}
catch
{
// If we fail to return the SqlDatReader, we need to close the connection ourselves
if (connection != null) connection.Close();
throw;
}
}
public static DbDataReader uteDataReader(CommandType commandType, string commandText, params SqlParameter[] commandParameters)
{
if (SqlConnectionString == null || SqlConnectionString.Length == 0) throw new ArgumentNullException("ConnectionString");
SqlConnection connection = null;
try
{
connection = new SqlConnection(SqlConnectionString);

connection.Open();
return uteDataReader(connection, (SqlTransaction)null, commandType, commandText, commandParameters);
}
catch
{
// If we fail to return the SqlDatReader, we need to close the connection ourselves
if (connection != null) connection.Close();
throw;
}
}
public static DbDataReader uteDataReader(CommandType commandType, string commandText)
{
return uteDataReader(commandType, commandText, (SqlParameter[])null);
}
public static DbDataReader uteDataReader(string commandText)
{
return uteDataReader(CommandType.Text, commandText);
}
public static DbDataReader uteDataReader(SqlConnection connection, out List outParameters, string commandText, CommandType commandType, params SqlParameter[] commandParameters)
{
DbDataReader reader = null;
outParameters = new List();
try
{
bool mustCloseConnection = false;
SqlCommand Command = new SqlCommand();
PrepareCommand(connection, Command, (SqlTransaction)null, commandType, commandText, commandParameters, out mustCloseConnection);

reader = Command.uteReader(System.Data.CommandBehavior.CloseConnection);// (CommandBehavior.CloseConnection);
Command.Parameters.Clear();//清空
Command.Dispose();

}
catch (Exception ex)
{
}
return reader;
}
public static DbDataReader uteDataReader(out List outParameters, string SqlSPro, params SqlParameter[] commandParameters)
{
if (SqlConnectionString == null || SqlConnectionString.Length == 0) throw new ArgumentNullException("ConnectionString");
SqlConnection connection = null;
try
{
connection = new SqlConnection(SqlConnectionString);

connection.Open();
return uteDataReader(connection, out outParameters, SqlSPro, CommandType.StoredProcedure, commandParameters);
}
catch
{
// If we fail to return the SqlDatReader, we need to close the connection ourselves
if (connection != null) connection.Close();
throw;
}
}
#endregion

#region uteDataRow 返回成果集中第一行
///
/// 履行指定命据库连接字符串的号令,返回DataSet第一行.
///

/// 存储过程名称或SQL语句
/// 号令类型 (存储过程,号令文本或其它)
/// 参数
/// 返回一个包含成果集的DataSet中的第一行
public static DataRow uteDataRow(SqlTransaction transaction, string commandText, CommandType commandType, params SqlParameter[] commandParameters)
{
try
{
DataRow row = null;
DataSet ds = uteDataSet(transaction, commandText, commandType, commandParameters);
if (ds.Tables[0].Rows.Count > 0)
{
row = (DataRow)ds.Tables[0].Rows[0];
}
ds.Dispose();
return row;
}
catch
{
return null;
}
}
public static DataRow uteDataRow(string commandText, CommandType commandType)
{
return uteDataRow((SqlTransaction)null, commandText, commandType, (SqlParameter[])null);
}
public static DataRow uteDataRow(string commandText, CommandType commandType, params SqlParameter[] commandParameters)
{
return uteDataRow((SqlTransaction)null, commandText, commandType, commandParameters);
}
public static DataRow uteDataRow(string commandText)
{
return uteDataRow((SqlTransaction)null, commandText,香港服务器, CommandType.Text, (SqlParameter[])null);
}
#endregion

#region uteNonQuery办法
public static int uteNonQuery(ref Hashtable OutPut, string commandText, params SqlParameter[] commandParameters)
{
if (_SqlConnectionString == null || _SqlConnectionString.Length == 0) throw new ArgumentNullException("ConnectionString");

using (SqlConnection connection = new SqlConnection(_SqlConnectionString))
{
connection.Open();
// 创建DbCommand号令,并进行预处理惩罚

bool mustCloseConnection = false;
SqlCommand Command = new SqlCommand();
PrepareCommand(connection, Command, (SqlTransaction)null, CommandType.StoredProcedure, commandText, commandParameters, out mustCloseConnection);

// 履行号令
int retval = Command.uteNonQuery();
for (int i = 0; i {
if (Command.Parameters[i].Direction == ParameterDirection.Output)
{
if (!OutPut.Contains(Command.Parameters[i].ParameterName.ToString()))
{
OutPut.Add(Command.Parameters[i].ParameterName.ToString(), Command.Parameters[i].Value.ToString());
}
}
}
// 清除参数,以便再次应用.
Command.Parameters.Clear();

Command.Dispose();

return retval;
}
}
///
/// DataTable批量添加到数据库
///

/// 要写入的表名
/// DataTable表
public static void CopyutNonQuery(string TableName, DataTable dt)
{
if (SqlConnectionString == null || SqlConnectionString.Length == 0) throw new ArgumentNullException("ConnectionString");
using (SqlConnection connection = new SqlConnection(SqlConnectionString))
{
connection.Open();
using (SqlTransaction Trans = connection.BeginTransaction())
{
using (SqlBulkCopy sqlBC = new SqlBulkCopy(connection, SqlBulkCopyOptions.FireTriggers, Trans))
{
try
{
//一次批量的插入的数据量
sqlBC.BatchSize = dt.Rows.Count;
//超时之前操纵完成所容许的秒数,若是超时则事务不会提交 ,数据将回滚,所有已复制的行都邑从目标表中移除
sqlBC.BulkCopyTimeout = 360;

//設定 NotifyAfter 属性,以便在每插入10000 条数据时,呼唤响应事务。
// sqlBC.NotifyAfter = 1000;
// sqlBC.SqlRowsCopied += new SqlRowsCopiedEventHandler(OnSqlRowsCopied);

//设置要批量写入的表
sqlBC.DestinationTableName = TableName;

//自定义的datatable和数据库的字段进行对应
//sqlBC.ColumnMappings.Add("id", "tel");
//sqlBC.ColumnMappings.Add("name", "neirong");
//for (int i = 0; i //{
// sqlBC.ColumnMappings.Add(dtColum[i].ColumnName.ToString(), dtColum[i].ColumnName.ToString());
//}
//批量写入
sqlBC.WriteToServer(dt);
Trans.Commit();
}
catch
{
Trans.Rollback();
}

}
}
}
}
///
/// 履行指定命据库连接对象的号令
///

/// 号令类型(存储过程,号令文本或其它.)
/// T存储过程名称或SQL语句
/// SqlParamter参数数组
/// 返回影响的行数
public static int uteNonQuery(CommandType commandType, string commandText, params SqlParameter[] commandParameters)
{
if (SqlConnectionString == null || SqlConnectionString.Length == 0) throw new ArgumentNullException("ConnectionString");

using (SqlConnection connection = new SqlConnection(SqlConnectionString))
{
connection.Open();
// 创建DbCommand号令,并进行预处理惩罚

bool mustCloseConnection = false;
SqlCommand Command = new SqlCommand();
PrepareCommand(connection, Command, (SqlTransaction)null, commandType, commandText, commandParameters, out mustCloseConnection);

// 履行号令
int retval = Command.uteNonQuery();
// 清除参数,以便再次应用.
Command.Parameters.Clear();

Command.Dispose();

return retval;
}
}
public static int uteNonQuery(SqlTransaction Transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
{

bool mustCloseConnection = false;
SqlCommand Command = new SqlCommand(); ;
PrepareCommand(Transaction.Connection, Command, Transaction, commandType, commandText, commandParameters, out mustCloseConnection);

try
{
// 履行号令
int retval = Command.uteNonQuery();

// 清除参数,以便再次应用.
Command.Parameters.Clear();
if (Transaction != null)
{
Transaction.Commit();
}

Command.Dispose();
if (mustCloseConnection)
{
Transaction.Connection.Close();
Transaction.Connection.Dispose();
}
return retval;
}
catch (Exception ex)
{
if (Transaction != null)
{
Transaction.Rollback();
}

Command.Dispose();
return 0;
}
}
public static int uteNonQuery(out int Scope_Identity, SqlTransaction Transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
{
Scope_Identity = 0;


bool mustCloseConnection = false;
SqlCommand Command = new SqlCommand();
PrepareCommand(Transaction.Connection, Command, Transaction, commandType, commandText, commandParameters, out mustCloseConnection);

try
{
// 履行号令
int retval = Command.uteNonQuery();
// 清除参数,以便再次应用.
Command.Parameters.Clear();
Command.CommandType = CommandType.Text;
Command.CommandText = "SELECT SCOPE_IDENTITY()";
Scope_Identity = int.Parse(Command.uteScalar().ToString());

Command.Dispose();
if (mustCloseConnection)
{
Transaction.Connection.Close();
Transaction.Connection.Dispose();
}
return retval;
}
catch (Exception ex)
{
Command.Dispose();
Transaction.Connection.Close();
Transaction.Connection.Dispose();
return 0;
}
}
///
/// 履行指定命据库连接对象的号令,并输出最后履行的成果编号
///

/// 输出最后履行成果
/// 号令类型(存储过程,号令文本或其它.)
/// T存储过程名称或SQL语句
/// SqlParamter参数数组
/// 返回影响的行数
public static int uteNonQuery(out int Scope_Identity, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
{

Scope_Identity = 0;
if (SqlConnectionString == null || SqlConnectionString.Length == 0) throw new ArgumentNullException("ConnectionString");

using (SqlConnection connection = new SqlConnection(SqlConnectionString))
{

connection.Open();
// 创建DbCommand号令,并进行预处理惩罚

bool mustCloseConnection = false;
SqlCommand Command = new SqlCommand();
PrepareCommand(connection, Command, (SqlTransaction)null, commandType, commandText, commandParameters, out mustCloseConnection);

try
{
// 履行号令
int retval = Command.uteNonQuery();
// 清除参数,以便再次应用.
Command.Parameters.Clear();
Command.CommandType = CommandType.Text;
Command.CommandText = "SELECT SCOPE_IDENTITY()";
Scope_Identity = int.Parse(Command.uteScalar().ToString());

Command.Dispose();
return retval;
}
catch (Exception ex)
{

Command.Dispose();
return 0;
}
}
}
///
/// 履行指定命据库连接对象的号令
///

/// 一个有效的数据库连接对象
/// 号令类型(存储过程,号令文本或其它.)
/// 存储过程名称或SQL语句
/// 返回影响的行数
public static int uteNonQuery(CommandType commandType, string CommandText)
{
if (CommandText == null || CommandText.Length == 0) throw new ArgumentNullException("commandText");
return uteNonQuery(commandType, CommandText, (SqlParameter[])null);
}
///
/// 履行指定命据库连接对象的号令,将对象数组的值赋给存储过程参数.
///

/// 一个有效的数据库连接对象
/// 存储过程名
/// 分派给存储过程输入参数的对象数组
/// 返回影响的行数
public static int uteNonQuery(string spName,香港空间, params SqlParameter[] commandParameters)
{

if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

// 若是有参数值
if ((commandParameters != null) && (commandParameters.Length > 0))
{
return uteNonQuery(CommandType.StoredProcedure, spName, commandParameters);
}
else
{
return uteNonQuery(CommandType.StoredProcedure, spName);
}
}

///
/// 履行带事务的SQL语句
///

///
///
public static int uteNonQuery(string commandText)
{
if (commandText == null || commandText.Length == 0) throw new ArgumentNullException("commandText");
//SqlTransaction Transaction = BBDataProvider.Transaction;
if (SqlConnectionString == null || SqlConnectionString.Length == 0) throw new ArgumentNullException("ConnectionString");

using (SqlConnection connection = new SqlConnection(SqlConnectionString))
{
connection.Open();
SqlTransaction Transaction = connection.BeginTransaction();

return uteNonQuery(Transaction, CommandType.Text, commandText, (SqlParameter[])null);
}
}
///
/// 履行存储过程,返回Output成果
///

/// 存储过程名
/// 号令类型(存储过程)
/// SqlParamter参数数组
/// Output成果
public static List uteNonQuery(string commandText, CommandType commandType, params SqlParameter[] commandParameters)
{
if (SqlConnectionString == null || SqlConnectionString.Length == 0) throw new ArgumentNullException("ConnectionString");

using (SqlConnection connection = new SqlConnection(SqlConnectionString))
{
connection.Open();
bool mustCloseConnection = false;
SqlCommand Command = new SqlCommand();
PrepareCommand(connection, Command, (SqlTransaction)null, CommandType.StoredProcedure, commandText, commandParameters, out mustCloseConnection);
try
{
Command.uteNonQuery();
}
catch { }

List outParameters = new List();
for (int i = 0; i {
if (Command.Parameters[i].Direction == ParameterDirection.Output)
{
string[] parameteritem = { Command.Parameters[i].ParameterName.ToString(), Command.Parameters[i].Value.ToString() };
outParameters.Add(parameteritem);
}
}
Command.Parameters.Clear();//清空

Command.Dispose();
if (mustCloseConnection)
connection.Close();
return outParameters;
}
}

#endregion
}
} ,美国服务器

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn