diff --git a/AsyncPoco/AsyncPoco.cs b/AsyncPoco/AsyncPoco.cs
index 208ba1e5..489b0b5e 100644
--- a/AsyncPoco/AsyncPoco.cs
+++ b/AsyncPoco/AsyncPoco.cs
@@ -24,6 +24,8 @@
using System.Configuration;
using System.Data;
using System.Data.Common;
+using System.Diagnostics;
+using System.Dynamic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
@@ -36,34 +38,62 @@
namespace AsyncPoco
{
///
- /// The main Database class. You can either use this class directly, or derive from it.
+ /// The main Database class. You can either use this class directly, or derive from it.
///
- public class Database : IDisposable
+ public class Database : IDatabase
{
+ private static IEqualityComparer _columnComparer = StringComparer.InvariantCultureIgnoreCase;
+ public static IEqualityComparer ColumnComparer
+ {
+ get { return _columnComparer; }
+ set
+ {
+ _columnComparer = value;
+ MultiPocoFactory.FieldNameComparer = value;
+ PocoData.ColumnComparer = value;
+ EnumMapper.FieldComparer = value;
+ }
+ }
+
+ #region IDisposable
+
+ ///
+ /// Automatically close one open shared connection
+ ///
+ public void Dispose()
+ {
+ // Automatically close one open connection reference
+ // (Works with KeepConnectionAlive and manually opening a shared connection)
+ CloseSharedConnection();
+ }
+
+ #endregion
+
#region Constructors
+
///
- /// Construct a database using a supplied DbConnection
+ /// Construct a database using a supplied DbConnection
///
/// The DbConnection to use
///
- /// The supplied DbConnection will not be closed/disposed by PetaPoco - that remains
- /// the responsibility of the caller.
+ /// The supplied DbConnection will not be closed/disposed by PetaPoco - that remains
+ /// the responsibility of the caller.
///
public Database(DbConnection connection)
{
_sharedConnection = connection;
_connectionString = connection.ConnectionString;
- _sharedConnectionDepth = 2; // Prevent closing external connection
+ _sharedConnectionDepth = 2; // Prevent closing external connection
CommonConstruct();
}
///
- /// Construct a database using a supplied connections string and optionally a provider name
+ /// Construct a database using a supplied connections string and optionally a provider name
///
/// The DB connection string
/// The name of the DB provider to use
///
- /// PetaPoco will automatically close and dispose any connections it creates.
+ /// PetaPoco will automatically close and dispose any connections it creates.
///
public Database(string connectionString, string providerName)
{
@@ -73,7 +103,7 @@ public Database(string connectionString, string providerName)
}
///
- /// Construct a Database using a supplied connection string and a DbProviderFactory
+ /// Construct a Database using a supplied connection string and a DbProviderFactory
///
/// The connection string to use
/// The DbProviderFactory to use for instantiating DbConnection's
@@ -85,8 +115,8 @@ public Database(string connectionString, DbProviderFactory provider)
}
///
- /// Construct a Database using a supplied connectionString Name. The actual connection string and provider will be
- /// read from app/web.config.
+ /// Construct a Database using a supplied connectionString Name. The actual connection string and provider will be
+ /// read from app/web.config.
///
/// The name of the connection
public Database(string connectionStringName)
@@ -114,7 +144,7 @@ public Database(string connectionStringName)
}
///
- /// Provides common initialization for the various constructors
+ /// Provides common initialization for the various constructors
///
private void CommonConstruct()
{
@@ -128,7 +158,7 @@ private void CommonConstruct()
_factory = DbProviderFactories.GetFactory(_providerName);
// Resolve the DB Type
- string DBTypeName = (_factory == null ? _sharedConnection.GetType() : _factory.GetType()).Name;
+ var DBTypeName = (_factory == null ? _sharedConnection.GetType() : _factory.GetType()).Name;
_dbType = DatabaseType.Resolve(DBTypeName, _providerName);
// What character is used for delimiting parameters in SQL
@@ -137,33 +167,18 @@ private void CommonConstruct()
#endregion
- #region IDisposable
- ///
- /// Automatically close one open shared connection
- ///
- public void Dispose()
- {
- // Automatically close one open connection reference
- // (Works with KeepConnectionAlive and manually opening a shared connection)
- CloseSharedConnection();
- }
- #endregion
-
#region Connection Management
+
///
- /// When set to true the first opened connection is kept alive until this object is disposed
+ /// When set to true the first opened connection is kept alive until this object is disposed
///
- public bool KeepConnectionAlive
- {
- get;
- set;
- }
+ public bool KeepConnectionAlive { get; set; }
///
- /// Open a connection that will be used for all subsequent queries.
+ /// Open a connection that will be used for all subsequent queries.
///
///
- /// Calls to Open/CloseSharedConnection are reference counted and should be balanced
+ /// Calls to Open/CloseSharedConnection are reference counted and should be balanced
///
public virtual async Task OpenSharedConnectionAsync()
{
@@ -181,13 +196,13 @@ public virtual async Task OpenSharedConnectionAsync()
_sharedConnection = OnConnectionOpened(_sharedConnection);
if (KeepConnectionAlive)
- _sharedConnectionDepth++; // Make sure you call Dispose
+ _sharedConnectionDepth++; // Make sure you call Dispose
}
_sharedConnectionDepth++;
}
///
- /// Releases the shared connection
+ /// Releases the shared connection
///
public void CloseSharedConnection()
{
@@ -204,7 +219,7 @@ public void CloseSharedConnection()
}
///
- /// Provides access to the currently open shared connection (or null if none)
+ /// Provides access to the currently open shared connection (or null if none)
///
public IDbConnection Connection
{
@@ -214,28 +229,25 @@ public IDbConnection Connection
#endregion
#region Transaction Management
+
// Helper to create a transaction scope
///
- /// Starts or continues a transaction.
+ /// Starts or continues a transaction.
///
/// An ITransaction reference that must be Completed or disposed
///
- /// This method makes management of calls to Begin/End/CompleteTransaction easier.
- ///
- /// The usage pattern for this should be:
- ///
- /// using (var tx = db.GetTransaction())
- /// {
- /// // Do stuff
- /// db.Update(...);
- ///
+ /// This method makes management of calls to Begin/End/CompleteTransaction easier.
+ /// The usage pattern for this should be:
+ /// using (var tx = db.GetTransaction())
+ /// {
+ /// // Do stuff
+ /// db.Update(...);
/// // Mark the transaction as complete
/// tx.Complete();
- /// }
- ///
- /// Transactions can be nested but they must all be completed otherwise the entire
- /// transaction is aborted.
+ /// }
+ /// Transactions can be nested but they must all be completed otherwise the entire
+ /// transaction is aborted.
///
public Task GetTransactionAsync()
{
@@ -243,22 +255,22 @@ public Task GetTransactionAsync()
}
///
- /// Called when a transaction starts. Overridden by the T4 template generated database
- /// classes to ensure the same DB instance is used throughout the transaction.
+ /// Called when a transaction starts. Overridden by the T4 template generated database
+ /// classes to ensure the same DB instance is used throughout the transaction.
///
- public virtual void OnBeginTransaction()
- {
+ public virtual void OnBeginTransaction()
+ {
}
///
- /// Called when a transaction ends.
+ /// Called when a transaction ends.
///
- public virtual void OnEndTransaction()
- {
+ public virtual void OnEndTransaction()
+ {
}
///
- /// Starts a transaction scope, see GetTransaction() for recommended usage
+ /// Starts a transaction scope, see GetTransaction() for recommended usage
///
public virtual async Task BeginTransactionAsync()
{
@@ -271,11 +283,10 @@ public virtual async Task BeginTransactionAsync()
_transactionCancelled = false;
OnBeginTransaction();
}
-
}
///
- /// Internal helper to cleanup transaction
+ /// Internal helper to cleanup transaction
///
protected virtual void CleanupTransaction()
{
@@ -293,38 +304,39 @@ protected virtual void CleanupTransaction()
}
///
- /// Aborts the entire outer most transaction scope
+ /// Aborts the entire outer most transaction scope
///
///
- /// Called automatically by Transaction.Dispose()
- /// if the transaction wasn't completed.
+ /// Called automatically by Transaction.Dispose()
+ /// if the transaction wasn't completed.
///
public void AbortTransaction()
{
_transactionCancelled = true;
- if ((--_transactionDepth) == 0)
+ if (--_transactionDepth == 0)
CleanupTransaction();
}
///
- /// Marks the current transaction scope as complete.
+ /// Marks the current transaction scope as complete.
///
public void CompleteTransaction()
{
- if ((--_transactionDepth) == 0)
+ if (--_transactionDepth == 0)
CleanupTransaction();
}
#endregion
#region Command Management
+
///
- /// Add a parameter to a DB command
+ /// Add a parameter to a DB command
///
/// A reference to the IDbCommand to which the parameter is to be added
/// The value to assign to the parameter
/// Optional, a reference to the property info of the POCO property from which the value is coming.
- void AddParam(IDbCommand cmd, object value, PropertyInfo pi)
+ private void AddParam(IDbCommand cmd, object value, PropertyInfo pi)
{
// Convert value to from poco type to db type
if (pi != null)
@@ -359,7 +371,7 @@ void AddParam(IDbCommand cmd, object value, PropertyInfo pi)
value = _dbType.MapParameterValue(value);
var t = value.GetType();
- if (t.IsEnum) // PostgreSQL .NET driver wont cast enum to int
+ if (t.IsEnum) // PostgreSQL .NET driver wont cast enum to int
{
p.Value = (int)value;
}
@@ -373,9 +385,9 @@ void AddParam(IDbCommand cmd, object value, PropertyInfo pi)
{
// out of memory exception occurs if trying to save more than 4000 characters to SQL Server CE NText column. Set before attempting to set Size, or Size will always max out at 4000
if ((value as string).Length + 1 > 4000 && p.GetType().Name == "SqlCeParameter")
- p.GetType().GetProperty("SqlDbType").SetValue(p, SqlDbType.NText, null);
+ p.GetType().GetProperty("SqlDbType").SetValue(p, SqlDbType.NText, null);
- p.Size = Math.Max((value as string).Length + 1, 4000); // Help query plan caching by using common size
+ p.Size = Math.Max((value as string).Length + 1, 4000); // Help query plan caching by using common size
p.Value = value;
}
else if (t == typeof(AnsiString))
@@ -387,7 +399,8 @@ void AddParam(IDbCommand cmd, object value, PropertyInfo pi)
}
else if (value.GetType().Name == "SqlGeography") //SqlGeography is a CLR Type
{
- p.GetType().GetProperty("UdtTypeName").SetValue(p, "geography", null); //geography is the equivalent SQL Server Type
+ p.GetType().GetProperty("UdtTypeName").SetValue(p, "geography", null);
+ //geography is the equivalent SQL Server Type
p.Value = value;
}
@@ -407,7 +420,8 @@ void AddParam(IDbCommand cmd, object value, PropertyInfo pi)
}
// Create a command
- static Regex rxParamsPrefix = new Regex(@"(? _paramPrefix + m.Value.Substring(1));
- sql = sql.Replace("@@", "@"); // <- double @@ escapes a single @
+ sql = sql.Replace("@@", "@"); // <- double @@ escapes a single @
// Create the command and add parameters
var cmd = connection.CreateCommand();
@@ -437,74 +451,76 @@ public DbCommand CreateCommand(DbConnection connection, string sql, params objec
_dbType.PreExecute(cmd);
// Call logging
- if (!String.IsNullOrEmpty(sql))
+ if (!string.IsNullOrEmpty(sql))
DoPreExecute(cmd);
return cmd;
}
+
#endregion
#region Exception Reporting and Logging
///
- /// Called if an exception occurs during processing of a DB operation. Override to provide custom logging/handling.
+ /// Called if an exception occurs during processing of a DB operation. Override to provide custom logging/handling.
///
/// The exception instance
/// True to re-throw the exception, false to suppress it
public virtual bool OnException(Exception x)
{
- System.Diagnostics.Debug.WriteLine(x.ToString());
- System.Diagnostics.Debug.WriteLine(LastCommand);
+ Debug.WriteLine(x.ToString());
+ Debug.WriteLine(LastCommand);
return true;
}
///
- /// Called when DB connection opened
+ /// Called when DB connection opened
///
/// The newly opened DbConnection
/// The same or a replacement DbConnection
///
- /// Override this method to provide custom logging of opening connection, or
- /// to provide a proxy DbConnection.
+ /// Override this method to provide custom logging of opening connection, or
+ /// to provide a proxy DbConnection.
///
- public virtual DbConnection OnConnectionOpened(DbConnection conn)
- {
- return conn;
+ public virtual DbConnection OnConnectionOpened(DbConnection conn)
+ {
+ return conn;
}
///
- /// Called when DB connection closed
+ /// Called when DB connection closed
///
/// The soon to be closed IDBConnection
- public virtual void OnConnectionClosing(IDbConnection conn)
- {
+ public virtual void OnConnectionClosing(IDbConnection conn)
+ {
}
///
- /// Called just before an DB command is executed
+ /// Called just before an DB command is executed
///
/// The command to be executed
///
- /// Override this method to provide custom logging of commands and/or
- /// modification of the IDbCommand before it's executed
+ /// Override this method to provide custom logging of commands and/or
+ /// modification of the IDbCommand before it's executed
///
- public virtual void OnExecutingCommand(IDbCommand cmd)
- {
+ public virtual void OnExecutingCommand(IDbCommand cmd)
+ {
}
///
- /// Called on completion of command execution
+ /// Called on completion of command execution
///
/// The IDbCommand that finished executing
- public virtual void OnExecutedCommand(IDbCommand cmd)
- {
+ public virtual void OnExecutedCommand(IDbCommand cmd)
+ {
}
#endregion
#region operation: Execute
+
///
- /// Executes a non-query command
+ /// Executes a non-query command
///
/// The SQL statement to execute
/// Arguments to any embedded parameters in the SQL
@@ -537,7 +553,7 @@ public virtual async Task ExecuteAsync(string sql, params object[] args)
}
///
- /// Executes a non-query command
+ /// Executes a non-query command
///
/// An SQL builder object representing the query and it's arguments
/// The number of rows affected
@@ -551,7 +567,7 @@ public Task ExecuteAsync(Sql sql)
#region operation: ExecuteScalarAsync
///
- /// Executes a query and return the first column of the first row in the result set.
+ /// Executes a query and return the first column of the first row in the result set.
///
/// The type that the result value should be cast to
/// The SQL query to execute
@@ -566,12 +582,12 @@ public virtual async Task ExecuteScalarAsync(string sql, params object[] a
{
using (var cmd = CreateCommand(_sharedConnection, sql, args))
{
- object val = await cmd.ExecuteScalarAsync();
+ var val = await cmd.ExecuteScalarAsync();
OnExecutedCommand(cmd);
// Handle nullable types
- Type u = Nullable.GetUnderlyingType(typeof(T));
- if (u != null && val == null)
+ var u = Nullable.GetUnderlyingType(typeof(T));
+ if (u != null && val == null)
return default(T);
return (T)Convert.ChangeType(val, u ?? typeof(T));
@@ -591,7 +607,7 @@ public virtual async Task ExecuteScalarAsync(string sql, params object[] a
}
///
- /// Executes a query and return the first column of the first row in the result set.
+ /// Executes a query and return the first column of the first row in the result set.
///
/// The type that the result value should be cast to
/// An SQL builder object representing the query and it's arguments
@@ -606,7 +622,7 @@ public Task ExecuteScalarAsync(Sql sql)
#region operation: Fetch
///
- /// Runs a query and returns the result set as a typed list
+ /// Runs a query and returns the result set as a typed list
///
/// The Type representing a row in the result set
/// The SQL query to execute
@@ -620,12 +636,12 @@ public async Task> FetchAsync(string sql, params object[] args)
}
///
- /// Runs a query and returns the result set as a typed list
+ /// Runs a query and returns the result set as a typed list
///
/// The Type representing a row in the result set
/// An SQL builder object representing the query and it's arguments
/// A List holding the results of the query
- public Task> FetchAsync(Sql sql)
+ public Task> FetchAsync(Sql sql)
{
return FetchAsync(sql.SQL, sql.Arguments);
}
@@ -635,8 +651,8 @@ public Task> FetchAsync(Sql sql)
#region operation: Page
///
- /// Starting with a regular SELECT statement, derives the SQL statements required to query a
- /// DB for a page of records and the total number of records
+ /// Starting with a regular SELECT statement, derives the SQL statements required to query a
+ /// DB for a page of records and the total number of records
///
/// The Type representing a row in the result set
/// The number of rows to skip before the start of the page
@@ -645,7 +661,8 @@ public Task> FetchAsync(Sql sql)
/// Arguments to any embedded parameters in the SQL
/// Outputs the SQL statement to query for the total number of matching rows
/// Outputs the SQL statement to retrieve a single page of matching rows
- void BuildPageQueries(long skip, long take, string sql, ref object[] args, out string sqlCount, out string sqlPage)
+ private void BuildPageQueries(long skip, long take, string sql, ref object[] args, out string sqlCount,
+ out string sqlPage)
{
// Add auto select clause
if (EnableAutoSelect)
@@ -661,7 +678,7 @@ void BuildPageQueries(long skip, long take, string sql, ref object[] args, ou
}
///
- /// Retrieves a page of records and the total number of available records
+ /// Retrieves a page of records and the total number of available records
///
/// The Type representing a row in the result set
/// The 1 based page number to retrieve
@@ -672,10 +689,12 @@ void BuildPageQueries(long skip, long take, string sql, ref object[] args, ou
/// Arguments to any embedded parameters in the sqlPage statement
/// A Page of results
///
- /// This method allows separate SQL statements to be explicitly provided for the two parts of the page query.
- /// The page and itemsPerPage parameters are not used directly and are used simply to populate the returned Page object.
+ /// This method allows separate SQL statements to be explicitly provided for the two parts of the page query.
+ /// The page and itemsPerPage parameters are not used directly and are used simply to populate the returned Page
+ /// object.
///
- public async Task> PageAsync(long page, long itemsPerPage, string sqlCount, object[] countArgs, string sqlPage, object[] pageArgs)
+ public async Task> PageAsync(long page, long itemsPerPage, string sqlCount, object[] countArgs,
+ string sqlPage, object[] pageArgs)
{
// Save the one-time command time out and use it for both queries
var saveTimeout = OneTimeCommandTimeout;
@@ -689,7 +708,7 @@ public async Task> PageAsync(long page, long itemsPerPage, string sql
};
result.TotalPages = result.TotalItems / itemsPerPage;
- if ((result.TotalItems % itemsPerPage) != 0)
+ if (result.TotalItems % itemsPerPage != 0)
result.TotalPages++;
OneTimeCommandTimeout = saveTimeout;
@@ -701,9 +720,8 @@ public async Task> PageAsync(long page, long itemsPerPage, string sql
return result;
}
-
///
- /// Retrieves a page of records and the total number of available records
+ /// Retrieves a page of records and the total number of available records
///
/// The Type representing a row in the result set
/// The 1 based page number to retrieve
@@ -712,19 +730,19 @@ public async Task> PageAsync(long page, long itemsPerPage, string sql
/// Arguments to any embedded parameters in the SQL statement
/// A Page of results
///
- /// PetaPoco will automatically modify the supplied SELECT statement to only retrieve the
- /// records for the specified page. It will also execute a second query to retrieve the
- /// total number of records in the result set.
+ /// PetaPoco will automatically modify the supplied SELECT statement to only retrieve the
+ /// records for the specified page. It will also execute a second query to retrieve the
+ /// total number of records in the result set.
///
- public Task> PageAsync(long page, long itemsPerPage, string sql, params object[] args)
+ public Task> PageAsync(long page, long itemsPerPage, string sql, params object[] args)
{
string sqlCount, sqlPage;
- BuildPageQueries((page-1)*itemsPerPage, itemsPerPage, sql, ref args, out sqlCount, out sqlPage);
+ BuildPageQueries((page - 1) * itemsPerPage, itemsPerPage, sql, ref args, out sqlCount, out sqlPage);
return PageAsync(page, itemsPerPage, sqlCount, args, sqlPage, args);
}
///
- /// Retrieves a page of records and the total number of available records
+ /// Retrieves a page of records and the total number of available records
///
/// The Type representing a row in the result set
/// The 1 based page number to retrieve
@@ -732,9 +750,9 @@ public Task> PageAsync(long page, long itemsPerPage, string sql, para
/// An SQL builder object representing the base SQL query and it's arguments
/// A Page of results
///
- /// PetaPoco will automatically modify the supplied SELECT statement to only retrieve the
- /// records for the specified page. It will also execute a second query to retrieve the
- /// total number of records in the result set.
+ /// PetaPoco will automatically modify the supplied SELECT statement to only retrieve the
+ /// records for the specified page. It will also execute a second query to retrieve the
+ /// total number of records in the result set.
///
public Task> PageAsync(long page, long itemsPerPage, Sql sql)
{
@@ -742,7 +760,7 @@ public Task> PageAsync(long page, long itemsPerPage, Sql sql)
}
///
- /// Retrieves a page of records and the total number of available records
+ /// Retrieves a page of records and the total number of available records
///
/// The Type representing a row in the result set
/// The 1 based page number to retrieve
@@ -751,8 +769,9 @@ public Task> PageAsync(long page, long itemsPerPage, Sql sql)
/// An SQL builder object representing the SQL to retrieve a single page of results
/// A Page of results
///
- /// This method allows separate SQL statements to be explicitly provided for the two parts of the page query.
- /// The page and itemsPerPage parameters are not used directly and are used simply to populate the returned Page object.
+ /// This method allows separate SQL statements to be explicitly provided for the two parts of the page query.
+ /// The page and itemsPerPage parameters are not used directly and are used simply to populate the returned Page
+ /// object.
///
public Task> PageAsync(long page, long itemsPerPage, Sql sqlCount, Sql sqlPage)
{
@@ -764,7 +783,7 @@ public Task> PageAsync(long page, long itemsPerPage, Sql sqlCount, Sq
#region operation: Fetch (page)
///
- /// Retrieves a page of records (without the total count)
+ /// Retrieves a page of records (without the total count)
///
/// The Type representing a row in the result set
/// The 1 based page number to retrieve
@@ -773,8 +792,8 @@ public Task> PageAsync(long page, long itemsPerPage, Sql sqlCount, Sq
/// Arguments to any embedded parameters in the SQL statement
/// A List of results
///
- /// PetaPoco will automatically modify the supplied SELECT statement to only retrieve the
- /// records for the specified page.
+ /// PetaPoco will automatically modify the supplied SELECT statement to only retrieve the
+ /// records for the specified page.
///
public Task> FetchAsync(long page, long itemsPerPage, string sql, params object[] args)
{
@@ -782,7 +801,7 @@ public Task> FetchAsync(long page, long itemsPerPage, string sql, par
}
///
- /// Retrieves a page of records (without the total count)
+ /// Retrieves a page of records (without the total count)
///
/// The Type representing a row in the result set
/// The 1 based page number to retrieve
@@ -790,8 +809,8 @@ public Task> FetchAsync(long page, long itemsPerPage, string sql, par
/// An SQL builder object representing the base SQL query and it's arguments
/// A List of results
///
- /// PetaPoco will automatically modify the supplied SELECT statement to only retrieve the
- /// records for the specified page.
+ /// PetaPoco will automatically modify the supplied SELECT statement to only retrieve the
+ /// records for the specified page.
///
public Task> FetchAsync(long page, long itemsPerPage, Sql sql)
{
@@ -803,7 +822,7 @@ public Task> FetchAsync(long page, long itemsPerPage, Sql sql)
#region operation: SkipTakeAsync
///
- /// Retrieves a range of records from result set
+ /// Retrieves a range of records from result set
///
/// The Type representing a row in the result set
/// The number of rows at the start of the result set to skip over
@@ -812,8 +831,8 @@ public Task> FetchAsync(long page, long itemsPerPage, Sql sql)
/// Arguments to any embedded parameters in the SQL statement
/// A List of results
///
- /// PetaPoco will automatically modify the supplied SELECT statement to only retrieve the
- /// records for the specified range.
+ /// PetaPoco will automatically modify the supplied SELECT statement to only retrieve the
+ /// records for the specified range.
///
public Task> SkipTakeAsync(long skip, long take, string sql, params object[] args)
{
@@ -823,7 +842,7 @@ public Task> SkipTakeAsync(long skip, long take, string sql, params o
}
///
- /// Retrieves a range of records from result set
+ /// Retrieves a range of records from result set
///
/// The Type representing a row in the result set
/// The number of rows at the start of the result set to skip over
@@ -831,79 +850,84 @@ public Task> SkipTakeAsync(long skip, long take, string sql, params o
/// An SQL builder object representing the base SQL query and it's arguments
/// A List of results
///
- /// PetaPoco will automatically modify the supplied SELECT statement to only retrieve the
- /// records for the specified range.
+ /// PetaPoco will automatically modify the supplied SELECT statement to only retrieve the
+ /// records for the specified range.
///
public Task> SkipTakeAsync(long skip, long take, Sql sql)
{
return SkipTakeAsync(skip, take, sql.SQL, sql.Arguments);
}
+
#endregion
#region operation: Query
///
- /// Runs an SQL query, asynchronously passing each result to a callback
+ /// Runs an SQL query, asynchronously passing each result to a callback
///
/// The Type representing a row in the result set
/// The SQL query
/// Callback to process each result
///
- /// For some DB providers, care should be taken to not start a new Query before finishing with
- /// and disposing the previous one. In cases where this is an issue, consider using Fetch which
- /// returns the results as a List.
+ /// For some DB providers, care should be taken to not start a new Query before finishing with
+ /// and disposing the previous one. In cases where this is an issue, consider using Fetch which
+ /// returns the results as a List.
///
- public Task QueryAsync(string sql, Action action) {
+ public Task QueryAsync(string sql, Action action)
+ {
return QueryAsync(sql, null, action);
}
///
- /// Runs an SQL query, asynchronously passing each result to a callback
+ /// Runs an SQL query, asynchronously passing each result to a callback
///
/// The Type representing a row in the result set
/// The SQL query
/// Callback to process each result, return false to stop iterating
///
- /// For some DB providers, care should be taken to not start a new Query before finishing with
- /// and disposing the previous one. In cases where this is an issue, consider using Fetch which
- /// returns the results as a List.
+ /// For some DB providers, care should be taken to not start a new Query before finishing with
+ /// and disposing the previous one. In cases where this is an issue, consider using Fetch which
+ /// returns the results as a List.
///
- public Task QueryAsync(string sql, Func func) {
+ public Task QueryAsync(string sql, Func func)
+ {
return QueryAsync(sql, null, func);
}
///
- /// Runs an SQL query, asynchronously passing each result to a callback
+ /// Runs an SQL query, asynchronously passing each result to a callback
///
/// The Type representing a row in the result set
/// The SQL query
/// Arguments to any embedded parameters in the SQL statement
/// Callback to process each result
///
- /// For some DB providers, care should be taken to not start a new Query before finishing with
- /// and disposing the previous one. In cases where this is an issue, consider using Fetch which
- /// returns the results as a List.
+ /// For some DB providers, care should be taken to not start a new Query before finishing with
+ /// and disposing the previous one. In cases where this is an issue, consider using Fetch which
+ /// returns the results as a List.
///
- public Task QueryAsync(string sql, object[] args, Action action) {
- return QueryAsync(sql, args, v => {
+ public Task QueryAsync(string sql, object[] args, Action action)
+ {
+ return QueryAsync(sql, args, v =>
+ {
action(v);
return true;
});
}
///
- /// Runs an SQL query, asynchronously passing each result to a callback
+ /// Runs an SQL query, asynchronously passing each result to a callback
///
/// The Type representing a row in the result set
/// The SQL query
/// Arguments to any embedded parameters in the SQL statement
/// Callback to process each result, return false to stop iterating
///
- /// For some DB providers, care should be taken to not start a new Query before finishing with
- /// and disposing the previous one. In cases where this is an issue, consider using Fetch which
- /// returns the results as a List.
+ /// For some DB providers, care should be taken to not start a new Query before finishing with
+ /// and disposing the previous one. In cases where this is an issue, consider using Fetch which
+ /// returns the results as a List.
///
- public virtual async Task QueryAsync(string sql, object[] args, Func func)
+ public virtual async Task QueryAsync(string sql, object[] args, Func func)
{
if (EnableAutoSelect)
sql = AutoSelectHelper.AddSelectClause(_dbType, sql);
@@ -927,8 +951,10 @@ public virtual async Task QueryAsync(string sql, object[] args, Func
return;
}
- var factory = pd.GetFactory(cmd.CommandText, _sharedConnection.ConnectionString, 0, r.FieldCount, r) as Func;
- using (r) {
+ var factory =
+ pd.GetFactory(cmd.CommandText, _sharedConnection.ConnectionString, 0, r.FieldCount, r) as Func;
+ using (r)
+ {
var keepGoing = true;
while (keepGoing)
{
@@ -960,33 +986,33 @@ public virtual async Task QueryAsync(string sql, object[] args, Func
}
///
- /// Runs an SQL query, asynchronously passing each result to a callback
+ /// Runs an SQL query, asynchronously passing each result to a callback
///
/// The Type representing a row in the result set
/// An SQL builder object representing the base SQL query and it's arguments
/// Callback to process each result
///
- /// For some DB providers, care should be taken to not start a new Query before finishing with
- /// and disposing the previous one. In cases where this is an issue, consider using Fetch which
- /// returns the results as a List.
+ /// For some DB providers, care should be taken to not start a new Query before finishing with
+ /// and disposing the previous one. In cases where this is an issue, consider using Fetch which
+ /// returns the results as a List.
///
- public Task QueryAsync(Sql sql, Action action)
+ public Task QueryAsync(Sql sql, Action action)
{
return QueryAsync(sql.SQL, sql.Arguments, action);
}
///
- /// Runs an SQL query, asynchronously passing each result to a callback
+ /// Runs an SQL query, asynchronously passing each result to a callback
///
/// The Type representing a row in the result set
/// An SQL builder object representing the base SQL query and it's arguments
/// Callback to process each result, return false to stop iterating
///
- /// For some DB providers, care should be taken to not start a new Query before finishing with
- /// and disposing the previous one. In cases where this is an issue, consider using Fetch which
- /// returns the results as a List.
+ /// For some DB providers, care should be taken to not start a new Query before finishing with
+ /// and disposing the previous one. In cases where this is an issue, consider using Fetch which
+ /// returns the results as a List.
///
- public Task QueryAsync(Sql sql, Func func)
+ public Task QueryAsync(Sql sql, Func func)
{
return QueryAsync(sql.SQL, sql.Arguments, func);
}
@@ -996,7 +1022,7 @@ public Task QueryAsync(Sql sql, Func func)
#region operation: Exists
///
- /// Checks for the existance of a row matching the specified condition
+ /// Checks for the existance of a row matching the specified condition
///
/// The Type representing the table being queried
/// The SQL expression to be tested for (ie: the WHERE expression)
@@ -1010,12 +1036,13 @@ public async Task ExistsAsync(string sqlCondition, params object[] args
}
///
- /// Checks for the existance of a row with the specified primary key value.
+ /// Checks for the existance of a row with the specified primary key value.
///
/// The Type representing the table being queried
/// The primary key value to look for
/// True if a record with the specified primary key value exists.
- public Task ExistsAsync(object primaryKey) {
+ public Task ExistsAsync(object primaryKey)
+ {
var index = 0;
var pk = GetPrimaryKeyValues(PocoData.ForType(typeof(T)).TableInfo.PrimaryKey, primaryKey);
return ExistsAsync(BuildPrimaryKeySql(pk, ref index), pk.Select(x => x.Value).ToArray());
@@ -1026,15 +1053,15 @@ public Task ExistsAsync(object primaryKey) {
#region operation: linq style (Exists, Single, SingleOrDefault etc...)
///
- /// Returns the record with the specified primary key value
+ /// Returns the record with the specified primary key value
///
/// The Type representing a row in the result set
/// The primary key value of the record to fetch
/// The single record matching the specified primary key value
///
- /// Throws an exception if there are zero or more than one record with the specified primary key value.
+ /// Throws an exception if there are zero or more than one record with the specified primary key value.
///
- public Task SingleAsync(object primaryKey)
+ public Task SingleAsync(object primaryKey)
{
var index = 0;
var pk = GetPrimaryKeyValues(PocoData.ForType(typeof(T)).TableInfo.PrimaryKey, primaryKey);
@@ -1042,15 +1069,15 @@ public Task SingleAsync(object primaryKey)
}
///
- /// Returns the record with the specified primary key value, or the default value if not found
+ /// Returns the record with the specified primary key value, or the default value if not found
///
/// The Type representing a row in the result set
/// The primary key value of the record to fetch
/// The single record matching the specified primary key value
///
- /// If there are no records with the specified primary key value, default(T) (typically null) is returned.
+ /// If there are no records with the specified primary key value, default(T) (typically null) is returned.
///
- public Task SingleOrDefaultAsync(object primaryKey)
+ public Task SingleOrDefaultAsync(object primaryKey)
{
var index = 0;
var pk = GetPrimaryKeyValues(PocoData.ForType(typeof(T)).TableInfo.PrimaryKey, primaryKey);
@@ -1058,44 +1085,46 @@ public Task SingleOrDefaultAsync(object primaryKey)
}
///
- /// Runs a query that should always return a single row.
+ /// Runs a query that should always return a single row.
///
/// The Type representing a row in the result set
/// The SQL query
/// Arguments to any embedded parameters in the SQL statement
/// The single record matching the specified primary key value
///
- /// Throws an exception if there are zero or more than one matching record
+ /// Throws an exception if there are zero or more than one matching record
///
public async Task SingleAsync(string sql, params object[] args)
{
var count = 0;
- T poco = default(T);
- await QueryAsync(sql, args, v => {
+ var poco = default(T);
+ await QueryAsync(sql, args, v =>
+ {
poco = v;
count++;
return count <= 2;
});
if (count == 0)
throw new InvalidOperationException("Sequence contains no elements.");
- else if (count > 1)
+ if (count > 1)
throw new InvalidOperationException("Sequence contains more than one element.");
return poco;
}
///
- /// Runs a query that should always return either a single row, or no rows
+ /// Runs a query that should always return either a single row, or no rows
///
/// The Type representing a row in the result set
/// The SQL query
/// Arguments to any embedded parameters in the SQL statement
/// The single record matching the specified primary key value, or default(T) if no matching rows
- public async Task SingleOrDefaultAsync(string sql, params object[] args)
+ public async Task SingleOrDefaultAsync(string sql, params object[] args)
{
var count = 0;
- T poco = default(T);
- await QueryAsync(sql, args, v => {
+ var poco = default(T);
+ await QueryAsync(sql, args, v =>
+ {
poco = v;
count++;
return count <= 2;
@@ -1107,17 +1136,18 @@ await QueryAsync(sql, args, v => {
}
///
- /// Runs a query that should always return at least one return
+ /// Runs a query that should always return at least one return
///
/// The Type representing a row in the result set
/// The SQL query
/// Arguments to any embedded parameters in the SQL statement
/// The first record in the result set
- public async Task FirstAsync(string sql, params object[] args)
+ public async Task FirstAsync(string sql, params object[] args)
{
var gotIt = false;
- T poco = default(T);
- await QueryAsync(sql, args, v => {
+ var poco = default(T);
+ await QueryAsync(sql, args, v =>
+ {
poco = v;
gotIt = true;
return false;
@@ -1129,16 +1159,17 @@ await QueryAsync(sql, args, v => {
}
///
- /// Runs a query and returns the first record, or the default value if no matching records
+ /// Runs a query and returns the first record, or the default value if no matching records
///
/// The Type representing a row in the result set
/// The SQL query
/// Arguments to any embedded parameters in the SQL statement
/// The first record in the result set, or default(T) if no matching rows
- public async Task FirstOrDefaultAsync(string sql, params object[] args)
+ public async Task FirstOrDefaultAsync(string sql, params object[] args)
{
- T poco = default(T);
- await QueryAsync(sql, args, v => {
+ var poco = default(T);
+ await QueryAsync(sql, args, v =>
+ {
poco = v;
return false;
});
@@ -1146,13 +1177,13 @@ await QueryAsync(sql, args, v => {
}
///
- /// Runs a query that should always return a single row.
+ /// Runs a query that should always return a single row.
///
/// The Type representing a row in the result set
/// An SQL builder object representing the query and it's arguments
/// The single record matching the specified primary key value
///
- /// Throws an exception if there are zero or more than one matching record
+ /// Throws an exception if there are zero or more than one matching record
///
public Task SingleAsync(Sql sql)
{
@@ -1160,43 +1191,44 @@ public Task SingleAsync(Sql sql)
}
///
- /// Runs a query that should always return either a single row, or no rows
+ /// Runs a query that should always return either a single row, or no rows
///
/// The Type representing a row in the result set
/// An SQL builder object representing the query and it's arguments
/// The single record matching the specified primary key value, or default(T) if no matching rows
- public Task SingleOrDefaultAsync(Sql sql)
+ public Task SingleOrDefaultAsync(Sql sql)
{
return SingleOrDefaultAsync(sql.SQL, sql.Arguments);
}
///
- /// Runs a query that should always return at least one return
+ /// Runs a query that should always return at least one return
///
/// The Type representing a row in the result set
/// An SQL builder object representing the query and it's arguments
/// The first record in the result set
- public Task FirstAsync(Sql sql)
+ public Task FirstAsync(Sql sql)
{
return FirstAsync(sql.SQL, sql.Arguments);
}
///
- /// Runs a query and returns the first record, or the default value if no matching records
+ /// Runs a query and returns the first record, or the default value if no matching records
///
/// The Type representing a row in the result set
/// An SQL builder object representing the query and it's arguments
/// The first record in the result set, or default(T) if no matching rows
- public Task FirstOrDefaultAsync(Sql sql)
+ public Task FirstOrDefaultAsync(Sql sql)
{
return FirstOrDefaultAsync(sql.SQL, sql.Arguments);
}
+
#endregion
#region operation: Insert
///
- /// Performs an SQL Insert
+ /// Performs an SQL Insert
///
/// The name of the table to insert into
/// The name of the primary key column of the table
@@ -1207,19 +1239,19 @@ public Task