Skip to content

Commit 5245879

Browse files
Merge pull request #77 from johelvisguzman/adonet
Fixed SQL Server Compact exception when performing a exists-trait for the ado-net repository
2 parents 153c1c4 + 532b01e commit 5245879

File tree

6 files changed

+762
-49
lines changed

6 files changed

+762
-49
lines changed

src/DotNetToolkit.Repository.AdoNet/AdoNetRepositoryBase.cs

Lines changed: 102 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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}\nFROM [{TableName}] AS [{mainTableAlias}]");
1495+
sb.Append($"SELECT\n\t{columns}\nFROM [{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

src/DotNetToolkit.Repository.AdoNet/Internal/ExtensionMethods.cs

Lines changed: 0 additions & 24 deletions
This file was deleted.

src/DotNetToolkit.Repository/Helpers/ConventionHelper.cs

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -143,45 +143,43 @@ public static int GetColumnOrder(this PropertyInfo pi)
143143
/// <param name="sourceType">The source type.</param>
144144
/// <param name="foreignType">The foreign type to match.</param>
145145
/// <returns>The name of the foreign key.</returns>
146-
public static string GetForeignKeyName(this Type sourceType, Type foreignType)
146+
public static PropertyInfo GetForeignKeyPropertyInfo(this Type sourceType, Type foreignType)
147147
{
148148
var properties = sourceType.GetRuntimeProperties().Where(x => x.IsMapped());
149149
var foreignPropertyInfo = properties.SingleOrDefault(x => x.PropertyType == foreignType);
150-
var foreignKeyName = string.Empty;
150+
151+
PropertyInfo propertyInfo = null;
151152

152153
if (foreignPropertyInfo != null)
153154
{
154155
var propertyInfosWithForeignKeys = properties.Where(x => x.GetCustomAttribute<ForeignKeyAttribute>() != null);
155156
if (propertyInfosWithForeignKeys.Any())
156157
{
157158
// Try to find by checking on the foreign key property
158-
foreignKeyName = propertyInfosWithForeignKeys
159+
propertyInfo = propertyInfosWithForeignKeys
159160
.Where(x => x.IsPrimitive())
160-
.SingleOrDefault(x => x.GetCustomAttribute<ForeignKeyAttribute>().Name.Equals(foreignPropertyInfo.Name))
161-
?.GetColumnName();
161+
.SingleOrDefault(x => x.GetCustomAttribute<ForeignKeyAttribute>().Name.Equals(foreignPropertyInfo.Name));
162162

163163
// Try to find by checking on the navigation property
164-
if (string.IsNullOrEmpty(foreignKeyName))
164+
if (propertyInfo == null)
165165
{
166-
foreignKeyName = properties
166+
propertyInfo = properties
167167
.Where(x => x.IsPrimitive())
168-
.SingleOrDefault(x => foreignPropertyInfo.GetCustomAttribute<ForeignKeyAttribute>().Name.Equals(x.GetColumnName()))
169-
?.GetColumnName();
168+
.SingleOrDefault(x => foreignPropertyInfo.GetCustomAttribute<ForeignKeyAttribute>().Name.Equals(x.GetColumnName()));
170169
}
171170
}
172171

173172
// Try to find by naming convention
174-
if (string.IsNullOrEmpty(foreignKeyName))
173+
if (propertyInfo == null)
175174
{
176175
var foreignPrimaryKeyName = foreignType.GetPrimaryKeyPropertyInfo().GetColumnName();
177176

178-
foreignKeyName = properties
179-
.SingleOrDefault(x => x.Name == $"{foreignType.Name}{foreignPrimaryKeyName}")
180-
?.GetColumnName();
177+
propertyInfo = properties
178+
.SingleOrDefault(x => x.Name == $"{foreignPropertyInfo.Name}{foreignPrimaryKeyName}");
181179
}
182180
}
183181

184-
return foreignKeyName;
182+
return propertyInfo;
185183
}
186184

187185
/// <summary>
@@ -239,4 +237,4 @@ private static IEnumerable<string> GetDefaultPrimaryKeyNameChecks(Type entityTyp
239237
return new[] { suffix, entityType.Name + suffix };
240238
}
241239
}
242-
}
240+
}

src/DotNetToolkit.Repository/RepositoryAsyncBase.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -535,9 +535,6 @@ protected RepositoryAsyncBase(ILogger logger) : base(logger)
535535
if (selector == null)
536536
throw new ArgumentNullException(nameof(selector));
537537

538-
if (fetchStrategy == null)
539-
throw new ArgumentNullException(nameof(fetchStrategy));
540-
541538
return GetEntityAsync(key, fetchStrategy, selector, cancellationToken);
542539
}
543540

0 commit comments

Comments
 (0)