Files
ayanova7/source/Data/Data/Sql/SqlDatabase.cs
2018-06-29 19:47:36 +00:00

306 lines
13 KiB
C#

//===============================================================================
// Microsoft patterns & practices Enterprise Library
// Data Access Application Block
//===============================================================================
// Copyright © Microsoft Corporation. All rights reserved.
// Adapted from ACA.NET with permission from Avanade Inc.
// ACA.NET copyright © Avanade Inc. All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================
using System;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Xml;
//using GZTW.Common;
namespace GZTW.Data.Sql
{
/// <summary>
/// <para>Represents a Sql Server Database.</para>
/// </summary>
/// <remarks>
/// <para>
/// Internally uses Sql Server .NET Managed Provider from Microsoft (System.Data.SqlClient) to connect to the database.
/// </para>
/// </remarks>
public class SqlDatabase : GZTWDatabase
{
/// <summary>
/// Initialize a new instance of the <see cref="SqlDatabase"/> class.
/// </summary>
public SqlDatabase() : base()
{
}
public override void ClearPool()
{
//not implemented, for firebird only for now
}
/// <summary>
/// Get the DataBaseType enum for the active db type
/// Used by higher layers when some DB specific code needs to be
/// executed
/// </summary>
/// <value>
/// <para>DataBaseType enumeration value</para>
/// </value>
public override DataBaseType DBType
{
get
{
return DataBaseType.MSSQL;
}
}
/// <summary>
/// Get the schema fingerprint for database
/// </summary>
public override string SchemaFingerPrint
{
get
{
string _fingerprint = "";
using (SqlConnection cn = new SqlConnection(ConnectionString))
{
try
{
cn.Open();
System.Text.StringBuilder sb = new System.Text.StringBuilder();
DataTable t = new DataTable();
new SqlDataAdapter("select name from sys.tables order by name", cn).Fill(t);
foreach (DataRow drTable in t.Rows)
{
//My development database has this table in it for some reason
//should be ignored
if (drTable[0].ToString() == "sysdiagrams" || drTable[0].ToString().ToLowerInvariant().Contains("dtproperties")) continue;
sb.Append(drTable[0].ToString());
sb.Append("\r\n");
DataTable tColumns = new DataTable();
new SqlDataAdapter("SELECT c.name AS column_name, t.name AS type_name " +
"FROM sys.columns AS c " +
"JOIN sys.types AS t ON c.user_type_id=t.user_type_id " +
"WHERE c.object_id = OBJECT_ID('"+ drTable[0].ToString()+"') " +
"ORDER BY c.name; ", cn).Fill(tColumns);
foreach (DataRow drColumn in tColumns.Rows)
{
sb.Append("\t");
sb.Append(drColumn["column_name"].ToString());
//sb.Append(" ");
//sb.Append(drColumn["type_name"].ToString());
sb.Append("\r\n");
}
}
_fingerprint = sb.ToString().Trim();
}
catch
{
}
finally
{
if (cn != null)
cn.Close();
}
}
return _fingerprint;
}
}
/// <summary>
/// <para>Gets the parameter token used to delimit parameters for the Sql Database.</para>
/// </summary>
/// <value>
/// <para>The '@' symbol.</para>
/// </value>
protected override char ParameterToken
{
get { return '@'; }
}
/// <summary>
/// <para>Get the connection for this database.</para>
/// <seealso cref="IDbConnection"/>
/// <seealso cref="SqlConnection"/>
/// </summary>
/// <returns>
/// <para>The <see cref="SqlConnection"/> for this database.</para>
/// </returns>
public override IDbConnection GetConnection()
{
return new SqlConnection(ConnectionString);
}
/// <summary>
/// <para>Create a <see cref="SqlCommandWrapper"/> for a stored procedure.</para>
/// </summary>
/// <param name="storedProcedureName"><para>The name of the stored procedure.</para></param>
/// <returns><para>The <see cref="SqlCommandWrapper"/> for the stored procedure.</para></returns>
/// <exception cref="ArgumentNullException">
/// <para><paramref name="storedProcedureName"/> can not be <see langword="null"/> (Nothing in Visual Basic).</para>
/// </exception>
/// <exception cref="ArgumentException">
/// <para><paramref name="storedProcedureName"/> hast not been initialized.</para>
/// </exception>
// public override DBCommandWrapper GetStoredProcCommandWrapper(string storedProcedureName)
// {
// ArgumentValidation.CheckForNullReference(storedProcedureName, "storedProcedureName");
// ArgumentValidation.CheckForEmptyString(storedProcedureName, "storedProcedureName");
//
// return new SqlCommandWrapper(storedProcedureName, CommandType.StoredProcedure, ParameterToken);
// }
/// <summary>
/// <para>Create an <see cref="SqlCommandWrapper"/> for a stored procedure.</para>
/// </summary>
/// <param name="storedProcedureName"><para>The name of the stored procedure.</para></param>
/// <param name="parameterValues"><para>The list of parameters for the procedure.</para></param>
/// <returns><para>The <see cref="SqlCommandWrapper"/> for the stored procedure.</para></returns>
/// <remarks>
/// <para>The parameters for the stored procedure will be discovered and the values are assigned in positional order.</para>
/// </remarks>
/// <exception cref="ArgumentNullException">
/// <para><paramref name="storedProcedureName"/> can not be <see langword="null"/> (Nothing in Visual Basic).</para>
/// <para>- or -</para>
/// <para><paramref name="parameterValues"/> can not be <see langword="null"/> (Nothing in Visual Basic).</para>
/// </exception>
/// <exception cref="ArgumentException">
/// <para><paramref name="storedProcedureName"/> hast not been initialized.</para>
/// </exception>
// public override DBCommandWrapper GetStoredProcCommandWrapper(string storedProcedureName, params object[] parameterValues)
// {
// ArgumentValidation.CheckForNullReference(storedProcedureName, "storedProcedureName");
// ArgumentValidation.CheckForEmptyString(storedProcedureName, "storedProcedureName");
// ArgumentValidation.CheckForNullReference(parameterValues, "parameterValues");
//
// return new SqlCommandWrapper(storedProcedureName, CommandType.StoredProcedure, ParameterToken, parameterValues);
// }
/// <summary>
/// <para>Create an <see cref="SqlCommandWrapper"/> for a SQL query.</para>
/// </summary>
/// <param name="query"><para>The text of the query.</para></param>
/// <returns><para>The <see cref="SqlCommandWrapper"/> for the SQL query.</para></returns>
/// <exception cref="ArgumentNullException">
/// <para><paramref name="query"/> can not be <see langword="null"/> (Nothing in Visual Basic).</para>
/// </exception>
/// <exception cref="ArgumentException">
/// <para><paramref name="query"/> hast not been initialized.</para>
/// </exception>
public override DBCommandWrapper GetSqlStringCommandWrapper(string query)
{
ArgumentValidation.CheckForNullReference(query, "query");
ArgumentValidation.CheckForEmptyString(query, "query");
return new SqlCommandWrapper(query, CommandType.Text, ParameterToken);
}
/// <summary>
/// <para>Create a <see cref="SqlDataAdapter"/> with the given update behavior and connection.</para>
/// </summary>
/// <param name="updateBehavior">
/// <para>One of the <see cref="UpdateBehavior"/> values.</para>
/// </param>
/// <param name="connection">
/// <para>The open connection to the database.</para>
/// </param>
/// <returns>An <see cref="SqlDataAdapter"/>.</returns>
/// <exception cref="ArgumentNullException">
/// <para><paramref name="connection"/> can not be <see langword="null"/> (Nothing in Visual Basic).</para>
/// </exception>
protected override DbDataAdapter GetDataAdapter(UpdateBehavior updateBehavior, IDbConnection connection)
{
string queryStringToBeFilledInLater = String.Empty;
SqlDataAdapter adapter = new SqlDataAdapter(queryStringToBeFilledInLater, (SqlConnection)connection);
if (updateBehavior == UpdateBehavior.Continue)
{
adapter.RowUpdated += new SqlRowUpdatedEventHandler(OnSqlRowUpdated);
}
return adapter;
}
/// <summary>
/// <para>Executes the <see cref="SqlCommandWrapper"/> and returns an <see cref="XmlReader"/>.</para>
/// </summary>
/// <param name="command">
/// <para>The <see cref="SqlCommandWrapper"/> to execute.</para>
/// </param>
/// <returns>
/// <para>An <see cref="XmlReader"/> object.</para>
/// </returns>
public XmlReader ExecuteXmlReader(SqlCommandWrapper command)
{
IDbConnection connection = OpenConnection();
PrepareCommand(command, connection);
SqlCommand sqlCommand = command.Command as SqlCommand;
return DoExecuteXmlReader(sqlCommand);
}
/// <summary>
/// <para>Executes the <see cref="SqlCommandWrapper"/> in a transaction and returns an <see cref="XmlReader"/>.</para>
/// </summary>
/// <param name="command">
/// <para>The <see cref="SqlCommandWrapper"/> to execute.</para>
/// </param>
/// <param name="transaction">
/// <para>The <see cref="IDbTransaction"/> to execute the command within.</para>
/// </param>
/// <returns>
/// <para>An <see cref="XmlReader"/> object.</para>
/// </returns>
public XmlReader ExecuteXmlReader(SqlCommandWrapper command, IDbTransaction transaction)
{
PrepareCommand(command, transaction);
SqlCommand sqlCommand = command.Command as SqlCommand;
return DoExecuteXmlReader(sqlCommand);
}
/// <devdoc>
/// Execute the actual Xml Reader call.
/// </devdoc>
private XmlReader DoExecuteXmlReader(SqlCommand sqlCommand)
{
try
{
DateTime startTime = DateTime.Now;
XmlReader reader = sqlCommand.ExecuteXmlReader();
//Instrumentation.CommandExecuted(startTime);
return reader;
}
catch
{
//Instrumentation.CommandFailed(sqlCommand.CommandText, ConnectionStringNoCredentials);
throw;
}
}
/// <devdoc>
/// Listens for the RowUpdate event on a dataadapter to support UpdateBehavior.Continue
/// </devdoc>
private void OnSqlRowUpdated(object sender, SqlRowUpdatedEventArgs rowThatCouldNotBeWritten)
{
if (rowThatCouldNotBeWritten.RecordsAffected == 0)
{
if (rowThatCouldNotBeWritten.Errors != null)
{
rowThatCouldNotBeWritten.Row.RowError = SR.ExceptionMessageUpdateDataSetRowFailure;
rowThatCouldNotBeWritten.Status = UpdateStatus.SkipCurrentRow;
}
}
}
}
}