@@ -268,6 +268,32 @@ public IEnumerable<T> ExecuteList<T>(string cmdText, Func<DbDataReader, T> proje
268268 return ExecuteList < T > ( cmdText , CommandType . Text , projector ) ;
269269 }
270270
271+ /// <summary>
272+ /// Executes the query, and returns a new <see cref="DataTable " />.
273+ /// </summary>
274+ /// <param name="cmdText">The command text.</param>
275+ /// <param name="cmdType">The command type</param>
276+ /// <param name="parameters">The command parameters</param>
277+ /// <returns>A new <see cref="DataTable" />.</returns>
278+ public DataTable ExecuteDataTable ( string cmdText , CommandType cmdType , Dictionary < string , object > parameters = null )
279+ {
280+ using ( var connection = CreateConnection ( ) )
281+ {
282+ return ExecuteDataTable ( connection , cmdText , cmdType , parameters ) ;
283+ }
284+ }
285+
286+ /// <summary>
287+ /// Executes the query, and returns a new <see cref="DataTable " />.
288+ /// </summary>
289+ /// <param name="cmdText">The command text.</param>
290+ /// <param name="parameters">The command parameters</param>
291+ /// <returns>A new <see cref="DataTable" />.</returns>
292+ public DataTable ExecuteDataTable ( string cmdText , Dictionary < string , object > parameters = null )
293+ {
294+ return ExecuteDataTable ( cmdText , CommandType . Text , parameters ) ;
295+ }
296+
271297 /// <summary>
272298 /// Executes the query, and returns a new <see cref="Dictionary{TDictionaryKey, TElement}" /> according to the specified <paramref name="keyProjector" />, and <paramref name="elementProjector" />.
273299 /// </summary>
@@ -944,6 +970,42 @@ protected IEnumerable<T> ExecuteList<T>(DbConnection connection, string cmdText,
944970 return ExecuteList < T > ( connection , cmdText , CommandType . Text , projector ) ;
945971 }
946972
973+ /// <summary>
974+ /// Executes the query, and returns a new <see cref="DataTable " />.
975+ /// </summary>
976+ /// <param name="connection">The connection.</param>
977+ /// <param name="cmdText">The command text.</param>
978+ /// <param name="cmdType">The command type</param>
979+ /// <param name="parameters">The command parameters</param>
980+ /// <returns>A new <see cref="DataTable" />.</returns>
981+ protected virtual DataTable ExecuteDataTable ( DbConnection connection , string cmdText , CommandType cmdType , Dictionary < string , object > parameters = null )
982+ {
983+ using ( var adapter = Factory . CreateDataAdapter ( ) )
984+ {
985+ var command = CreateCommand ( connection , cmdText , cmdType , parameters ) ;
986+
987+ adapter . SelectCommand = command ;
988+
989+ var table = new DataTable ( ) ;
990+
991+ adapter . Fill ( table ) ;
992+
993+ return table ;
994+ }
995+ }
996+
997+ /// <summary>
998+ /// Executes the query, and returns a new <see cref="DataTable " />.
999+ /// </summary>
1000+ /// <param name="connection">The connection.</param>
1001+ /// <param name="cmdText">The command text.</param>
1002+ /// <param name="parameters">The command parameters</param>
1003+ /// <returns>A new <see cref="DataTable" />.</returns>
1004+ protected DataTable ExecuteDataTable ( DbConnection connection , string cmdText , Dictionary < string , object > parameters = null )
1005+ {
1006+ return ExecuteDataTable ( connection , cmdText , CommandType . Text , parameters ) ;
1007+ }
1008+
9471009 /// <summary>
9481010 /// Executes the query, and returns a new <see cref="Dictionary{TDictionaryKey, TElement}" /> according to the specified <paramref name="keyProjector" />, and <paramref name="elementProjector" />.
9491011 /// </summary>
@@ -1350,7 +1412,7 @@ private void PrepareSelectStatement(IFetchStrategy<TEntity> fetchStrategy, out D
13501412 var mainTablePrimaryKeyName = typeof ( TEntity ) . GetPrimaryKeyPropertyInfo ( ) . GetColumnName ( ) ;
13511413
13521414 // Default select
1353- var selectSql = string . Join ( ",\n \t " ,
1415+ var columns = string . Join ( ",\n \t " ,
13541416 SqlPropertiesMapping . Select ( x =>
13551417 {
13561418 var colAlias = cfg . GenerateColumnAlias ( x . Value ) ;
@@ -1367,7 +1429,7 @@ private void PrepareSelectStatement(IFetchStrategy<TEntity> fetchStrategy, out D
13671429 // the same type as the primary table
13681430 // Only do a join when the primary table has a foreign key property for the join table
13691431 var paths = mainTableProperties
1370- . Where ( x => x . IsComplex ( ) && ! string . IsNullOrEmpty ( x . PropertyType . GetForeignKeyName ( mainTableType ) ) )
1432+ . Where ( x => x . IsComplex ( ) && ! string . IsNullOrEmpty ( x . PropertyType . GetPrimaryKeyPropertyInfo ( ) ? . GetColumnName ( ) ) )
13711433 . Select ( x => x . Name )
13721434 . ToList ( ) ;
13731435
@@ -1389,13 +1451,13 @@ private void PrepareSelectStatement(IFetchStrategy<TEntity> fetchStrategy, out D
13891451 {
13901452 var joinStatementSb = new StringBuilder ( ) ;
13911453
1392- sb . Append ( $ "SELECT\n \t { selectSql } ") ;
1454+ sb . Append ( $ "SELECT\n \t { columns } ") ;
13931455
13941456 foreach ( var path in fetchStrategy . IncludePaths )
13951457 {
13961458 var joinTablePropertyInfo = mainTableProperties . Single ( x => x . Name . Equals ( path ) ) ;
13971459 var joinTableType = joinTablePropertyInfo . PropertyType ;
1398- var joinTableForeignKeyName = joinTableType . GetForeignKeyName ( mainTableType ) ;
1460+ var joinTableForeignKeyName = joinTableType . GetForeignKeyPropertyInfo ( mainTableType ) ? . GetColumnName ( ) ;
13991461
14001462 // Only do a join when the primary table has a foreign key property for the join table
14011463 if ( ! string . IsNullOrEmpty ( joinTableForeignKeyName ) )
@@ -1430,7 +1492,7 @@ private void PrepareSelectStatement(IFetchStrategy<TEntity> fetchStrategy, out D
14301492 }
14311493 else
14321494 {
1433- sb . Append ( $ "SELECT\n \t { selectSql } \n FROM [{ TableName } ] AS [{ mainTableAlias } ]") ;
1495+ sb . Append ( $ "SELECT\n \t { columns } \n FROM [{ TableName } ] AS [{ mainTableAlias } ]") ;
14341496 }
14351497
14361498 cfg . Sql = sb . ToString ( ) ;
@@ -1779,6 +1841,31 @@ protected override int GetCount(ISpecification<TEntity> criteria)
17791841 }
17801842 }
17811843
1844+ /// <summary>
1845+ /// A protected overridable method for determining whether the repository contains an entity that satisfies the criteria specified by the <paramref name="criteria" /> from the repository.
1846+ /// </summary>
1847+ protected override bool GetExist ( ISpecification < TEntity > criteria )
1848+ {
1849+ if ( criteria == null )
1850+ throw new ArgumentNullException ( nameof ( criteria ) ) ;
1851+
1852+ PrepareSelectStatement ( criteria , ( IQueryOptions < TEntity > ) null , out DbSqlSelectStatementConfig config ) ;
1853+
1854+ using ( var reader = ExecuteReader ( config . Sql , config . Parameters ) )
1855+ {
1856+ var hasRows = false ;
1857+
1858+ while ( reader . Read ( ) )
1859+ {
1860+ hasRows = true ;
1861+
1862+ break ;
1863+ }
1864+
1865+ return hasRows ;
1866+ }
1867+ }
1868+
17821869 /// <summary>
17831870 /// Gets a new <see cref="Dictionary{TDictionaryKey, TElement}" /> according to the specified <paramref name="keySelector" />, an element selector.
17841871 /// </summary>
@@ -1965,7 +2052,16 @@ public override void Dispose()
19652052
19662053 using ( var reader = await ExecuteReaderAsync ( config . Sql , config . Parameters , cancellationToken ) )
19672054 {
1968- return reader . HasRows ;
2055+ var hasRows = false ;
2056+
2057+ while ( await reader . ReadAsync ( cancellationToken ) )
2058+ {
2059+ hasRows = true ;
2060+
2061+ break ;
2062+ }
2063+
2064+ return hasRows ;
19692065 }
19702066 }
19712067
0 commit comments