@@ -50,12 +50,12 @@ public abstract class AdoNetRepositoryBase<TEntity, TKey> : RepositoryAsyncBase<
5050 /// <summary>
5151 /// Gets the name of the identity property.
5252 /// </summary>
53- protected PropertyInfo SqlIdentityProperty { get ; private set ; }
53+ protected PropertyInfo SqlIdentityPropertyInfo { get ; private set ; }
5454
5555 /// <summary>
5656 /// Gets the SQL properties.
5757 /// </summary>
58- protected Dictionary < string , PropertyInfo > SqlProperties { get ; private set ; }
58+ protected Dictionary < string , PropertyInfo > SqlPropertiesMapping { get ; private set ; }
5959
6060 /// <summary>
6161 /// Gets the name of the table.
@@ -1301,12 +1301,13 @@ protected virtual IEnumerable<IGrouping<TGroupKey, TElement>> ExecuteGroup<TGrou
13011301
13021302 private void Initialize ( )
13031303 {
1304- SqlProperties = typeof ( TEntity )
1304+ SqlPropertiesMapping = typeof ( TEntity )
13051305 . GetRuntimeProperties ( )
1306- . Where ( x => x . PropertyType . Namespace == "System" )
1307- . ToDictionary ( x => x . Name , x => x ) ;
1306+ . Where ( x => x . IsPrimitive ( ) && x . IsMapped ( ) )
1307+ . OrderBy ( x => x . GetColumnOrder ( ) )
1308+ . ToDictionary ( ConventionHelper . GetColumnName , x => x ) ;
13081309
1309- TableName = $ " { typeof ( TEntity ) . Name } " ;
1310+ TableName = typeof ( TEntity ) . GetTableName ( ) ;
13101311
13111312 DataRow autoIncrementDataRow = null ;
13121313
@@ -1326,8 +1327,14 @@ private void Initialize()
13261327
13271328 if ( autoIncrementDataRow != null )
13281329 {
1330+ var columnName = ( string ) autoIncrementDataRow [ "ColumnName" ] ;
1331+
1332+ SqlIdentityPropertyInfo = SqlPropertiesMapping . FirstOrDefault ( x => x . Key . Equals ( columnName ) ) . Value ;
1333+
1334+ if ( SqlIdentityPropertyInfo == null )
1335+ throw new InvalidOperationException ( string . Format ( Resources . InvalidColumnName , columnName ) ) ;
1336+
13291337 IsIdentity = true ;
1330- SqlIdentityProperty = SqlProperties . Select ( x => x . Value ) . First ( x => x . Name . Equals ( ( string ) autoIncrementDataRow [ "ColumnName" ] ) ) ;
13311338 }
13321339 }
13331340 }
@@ -1338,19 +1345,18 @@ private void PrepareSelectStatement(IFetchStrategy<TEntity> fetchStrategy, out D
13381345 var cfg = new DbSqlSelectStatementConfig ( ) ;
13391346
13401347 var mainTableType = typeof ( TEntity ) ;
1341- var mainTableAlias = cfg . GenerateTableAlias ( mainTableType , TableName ) ;
1348+ var mainTableAlias = cfg . GenerateTableAlias ( mainTableType ) ;
13421349 var mainTableProperties = mainTableType . GetRuntimeProperties ( ) ;
1343- var mainTablePrimaryKeyName = GetPrimaryKeyPropertyInfo ( ) . Name ;
1344-
1345- const string systemNameSpace = "System" ;
1350+ var mainTablePrimaryKeyName = typeof ( TEntity ) . GetPrimaryKeyPropertyInfo ( ) . GetColumnName ( ) ;
13461351
13471352 // Default select
13481353 var selectSql = string . Join ( ",\n \t " ,
1349- SqlProperties . Select ( x =>
1354+ SqlPropertiesMapping . Select ( x =>
13501355 {
1351- cfg . GenerateColumnAlias ( TableName , x . Key ) ;
1356+ var colAlias = cfg . GenerateColumnAlias ( x . Value ) ;
1357+ var colName = x . Value . GetColumnName ( ) ;
13521358
1353- return $ "[{ mainTableAlias } ].[{ x . Key } ] AS [{ x . Key } ]";
1359+ return $ "[{ mainTableAlias } ].[{ colName } ] AS [{ colAlias } ]";
13541360 } ) ) ;
13551361
13561362 // Check to see if we can automatically include some navigation properties (this seems to be the behavior of entity framework as well).
@@ -1360,15 +1366,9 @@ private void PrepareSelectStatement(IFetchStrategy<TEntity> fetchStrategy, out D
13601366 // Assumes we want to perform a join when the navigation property from the primary table has also a navigation property of
13611367 // the same type as the primary table
13621368 // Only do a join when the primary table has a foreign key property for the join table
1363- var paths = (
1364- from pi in mainTableProperties . Where ( x => x . PropertyType . Namespace != systemNameSpace )
1365- let jointTableType = pi . PropertyType
1366- let joinTableProperties = jointTableType . GetRuntimeProperties ( )
1367- where joinTableProperties . Any ( x => x . PropertyType == mainTableType )
1368- let joinTableForeignKeyName = joinTableProperties . SingleOrDefault ( x => x . Name == $ "{ TableName } { mainTablePrimaryKeyName } ") ? . Name
1369- where ! string . IsNullOrEmpty ( joinTableForeignKeyName )
1370- select pi . Name
1371- )
1369+ var paths = mainTableProperties
1370+ . Where ( x => x . IsComplex ( ) && ! string . IsNullOrEmpty ( x . PropertyType . GetForeignKeyName ( mainTableType ) ) )
1371+ . Select ( x => x . Name )
13721372 . ToList ( ) ;
13731373
13741374 if ( paths . Count > 0 )
@@ -1394,39 +1394,34 @@ select pi.Name
13941394 foreach ( var path in fetchStrategy . IncludePaths )
13951395 {
13961396 var joinTablePropertyInfo = mainTableProperties . Single ( x => x . Name . Equals ( path ) ) ;
1397- var jointTableType = joinTablePropertyInfo . PropertyType ;
1398- var joinTableProperties = jointTableType . GetRuntimeProperties ( ) ;
1397+ var joinTableType = joinTablePropertyInfo . PropertyType ;
1398+ var joinTableForeignKeyName = joinTableType . GetForeignKeyName ( mainTableType ) ;
13991399
1400- // Assumes we want to perform a join when the navigation property from the primary table has also a navigation property of
1401- // the same type as the primary table
1402- if ( joinTableProperties . Any ( x => x . PropertyType == mainTableType ) )
1400+ // Only do a join when the primary table has a foreign key property for the join table
1401+ if ( ! string . IsNullOrEmpty ( joinTableForeignKeyName ) )
14031402 {
1404- var joinTableForeignKeyName = joinTableProperties . SingleOrDefault ( x => x . Name == $ "{ TableName } { mainTablePrimaryKeyName } ") ? . Name ;
1403+ var joinTableProperties = joinTableType . GetRuntimeProperties ( ) ;
1404+ var joinTableName = joinTableType . GetTableName ( ) ;
1405+ var joinTableAlias = cfg . GenerateTableAlias ( joinTableType ) ;
1406+ var joinTableColumnNames = string . Join ( ",\n \t " ,
1407+ joinTableProperties
1408+ . Where ( x => x . IsPrimitive ( ) )
1409+ . Select ( x =>
1410+ {
1411+ var colAlias = cfg . GenerateColumnAlias ( x ) ;
1412+ var colName = x . GetColumnName ( ) ;
14051413
1406- // Only do a join when the primary table has a foreign key property for the join table
1407- if ( ! string . IsNullOrEmpty ( joinTableForeignKeyName ) )
1408- {
1409- var joinTableName = $ "{ joinTablePropertyInfo . PropertyType . Name } ";
1410- var joinTableAlias = cfg . GenerateTableAlias ( joinTablePropertyInfo . PropertyType , joinTableName ) ;
1411- var joinTableColumnNames = string . Join ( ",\n \t " ,
1412- joinTableProperties
1413- . Where ( x => x . PropertyType . Namespace == systemNameSpace )
1414- . Select ( x =>
1415- {
1416- var colAlias = cfg . GenerateColumnAlias ( joinTableName , x . Name ) ;
1417-
1418- return $ "[{ joinTableAlias } ].[{ x . Name } ] AS [{ colAlias } ]";
1419- } ) ) ;
1414+ return $ "[{ joinTableAlias } ].[{ colName } ] AS [{ colAlias } ]";
1415+ } ) ) ;
14201416
14211417
1422- sb . Append ( ",\n \t " ) ;
1423- sb . Append ( joinTableColumnNames ) ;
1418+ sb . Append ( ",\n \t " ) ;
1419+ sb . Append ( joinTableColumnNames ) ;
14241420
1425- joinStatementSb . Append ( "\n " ) ;
1426- joinStatementSb . Append ( $ "LEFT OUTER JOIN [{ joinTableName } ] AS [{ joinTableAlias } ] ON [{ mainTableAlias } ].[{ mainTablePrimaryKeyName } ] = [{ joinTableAlias } ].[{ joinTableForeignKeyName } ]") ;
1421+ joinStatementSb . Append ( "\n " ) ;
1422+ joinStatementSb . Append ( $ "LEFT OUTER JOIN [{ joinTableName } ] AS [{ joinTableAlias } ] ON [{ mainTableAlias } ].[{ mainTablePrimaryKeyName } ] = [{ joinTableAlias } ].[{ joinTableForeignKeyName } ]") ;
14271423
1428- cfg . JoinTablePropertiesMapping . Add ( jointTableType , joinTableProperties . ToDictionary ( x => x . Name , x => x ) ) ;
1429- }
1424+ cfg . JoinTablePropertiesMapping . Add ( joinTableType , joinTableProperties . ToDictionary ( x => x . GetColumnName ( ) , x => x ) ) ;
14301425 }
14311426 }
14321427
@@ -1480,8 +1475,8 @@ private void PrepareSelectStatement(ISpecification<TEntity> criteria, IQueryOpti
14801475 var tableType = ExpressionHelper . GetMemberExpression ( lambda ) . Expression . Type ;
14811476 var tableName = config . GetTableName ( tableType ) ;
14821477 var tableAlias = config . GetTableAlias ( tableName ) ;
1483- var sortingPropertyName = ExpressionHelper . GetPropertyName ( lambda ) ;
1484- var columnAlias = config . GetColumnAlias ( tableName , sortingPropertyName ) ;
1478+ var sortingPropertyInfo = ExpressionHelper . GetPropertyInfo ( lambda ) ;
1479+ var columnAlias = config . GetColumnAlias ( sortingPropertyInfo ) ;
14851480
14861481 sb . Append ( "\n " ) ;
14871482 sb . Append ( sortingOptions . IsDescending ? $ "ORDER BY [{ tableAlias } ].[{ columnAlias } ] DESC" : $ "ORDER BY [{ tableAlias } ].[{ columnAlias } ] ASC") ;
@@ -1502,7 +1497,8 @@ private void PrepareSelectStatement(ISpecification<TEntity> criteria, IQueryOpti
15021497
15031498 private void PrepareEntitySetStatement ( EntitySet entitySet , out string sql , out Dictionary < string , object > parameters )
15041499 {
1505- var properties = IsIdentity ? SqlProperties . Where ( x => ! x . Key . Equals ( SqlIdentityProperty . Name ) ) : SqlProperties ;
1500+ var primeryKeyColumnName = SqlIdentityPropertyInfo . GetColumnName ( ) ;
1501+ var properties = IsIdentity ? SqlPropertiesMapping . Where ( x => ! x . Key . Equals ( primeryKeyColumnName ) ) : SqlPropertiesMapping ;
15061502
15071503 parameters = new Dictionary < string , object > ( ) ;
15081504 sql = string . Empty ;
@@ -1511,42 +1507,46 @@ private void PrepareEntitySetStatement(EntitySet entitySet, out string sql, out
15111507 {
15121508 case EntityState . Added :
15131509 {
1514- var columnNames = string . Join ( ", " , properties . Select ( x => x . Key ) ) . TrimEnd ( ) ;
1515- var values = string . Join ( ",\n \t " , properties . Select ( x => $ "@{ x . Key } ") ) ;
1510+ var columnNames = string . Join ( ", " , properties . Select ( x => x . Value . GetColumnName ( ) ) ) . TrimEnd ( ) ;
1511+ var values = string . Join ( ", " , properties . Select ( x => $ "@{ x . Value . GetColumnName ( ) } ") ) . TrimEnd ( ) ;
15161512
15171513 sql = $ "INSERT INTO [{ TableName } ] ({ columnNames } )\n VALUES ({ values } )";
15181514
15191515 foreach ( var pi in properties )
15201516 {
1521- parameters . Add ( $ "@{ pi . Key } ", pi . Value . GetValue ( entitySet . Entity , null ) ) ;
1517+ parameters . Add ( $ "@{ pi . Value . GetColumnName ( ) } ", pi . Value . GetValue ( entitySet . Entity , null ) ) ;
15221518 }
15231519
15241520 if ( IsIdentity )
1525- parameters . Add ( $ "@{ SqlIdentityProperty . Name } ", SqlIdentityProperty . GetValue ( entitySet . Entity , null ) ) ;
1521+ parameters . Add ( $ "@{ primeryKeyColumnName } ", SqlIdentityPropertyInfo . GetValue ( entitySet . Entity , null ) ) ;
15261522
15271523 break ;
15281524 }
15291525 case EntityState . Removed :
15301526 {
1531- sql = $ "DELETE FROM [{ TableName } ]\n WHERE { SqlIdentityProperty . Name } = @{ SqlIdentityProperty . Name } ";
1527+ sql = $ "DELETE FROM [{ TableName } ]\n WHERE { primeryKeyColumnName } = @{ primeryKeyColumnName } ";
15321528
1533- parameters . Add ( $ "@{ SqlIdentityProperty . Name } ", SqlIdentityProperty . GetValue ( entitySet . Entity , null ) ) ;
1529+ parameters . Add ( $ "@{ primeryKeyColumnName } ", SqlIdentityPropertyInfo . GetValue ( entitySet . Entity , null ) ) ;
15341530
15351531 break ;
15361532 }
15371533 case EntityState . Modified :
15381534 {
1539- var values = string . Join ( ",\n \t " , properties . Select ( x => x . Key + " = " + $ "@{ x . Key } ") ) ;
1535+ var values = string . Join ( ",\n \t " , properties . Select ( x =>
1536+ {
1537+ var columnName = x . Value . GetColumnName ( ) ;
1538+ return columnName + " = " + $ "@{ columnName } ";
1539+ } ) ) ;
15401540
1541- sql = $ "UPDATE [{ TableName } ]\n SET { values } \n WHERE { SqlIdentityProperty . Name } = @{ SqlIdentityProperty . Name } ";
1541+ sql = $ "UPDATE [{ TableName } ]\n SET { values } \n WHERE { primeryKeyColumnName } = @{ primeryKeyColumnName } ";
15421542
15431543 foreach ( var pi in properties )
15441544 {
1545- parameters . Add ( $ "@{ pi . Key } ", pi . Value . GetValue ( entitySet . Entity , null ) ) ;
1545+ parameters . Add ( $ "@{ pi . Value . GetColumnName ( ) } ", pi . Value . GetValue ( entitySet . Entity , null ) ) ;
15461546 }
15471547
15481548 if ( IsIdentity )
1549- parameters . Add ( $ "@{ SqlIdentityProperty . Name } ", SqlIdentityProperty . GetValue ( entitySet . Entity , null ) ) ;
1549+ parameters . Add ( $ "@{ primeryKeyColumnName } ", SqlIdentityPropertyInfo . GetValue ( entitySet . Entity , null ) ) ;
15501550
15511551 break ;
15521552 }
@@ -1573,9 +1573,9 @@ private TElement AutoMap<TElement>(DbDataReader r, Expression<Func<TEntity, TEle
15731573 if ( value == DBNull . Value )
15741574 value = null ;
15751575
1576- if ( SqlProperties . ContainsKey ( name ) && ! r . IsDBNull ( r . GetOrdinal ( name ) ) )
1576+ if ( SqlPropertiesMapping . ContainsKey ( name ) && ! r . IsDBNull ( r . GetOrdinal ( name ) ) )
15771577 {
1578- SqlProperties [ name ] . SetValue ( entity , value ) ;
1578+ SqlPropertiesMapping [ name ] . SetValue ( entity , value ) ;
15791579 }
15801580 else if ( joinTableInstances != null )
15811581 {
@@ -1672,7 +1672,7 @@ protected override void SaveChanges()
16721672 {
16731673 var key = ExecuteScalar < TKey > ( connection , "SELECT @@IDENTITY" ) ;
16741674
1675- SetPrimaryKey ( entitySet . Entity , key ) ;
1675+ entitySet . Entity . SetPrimaryKeyPropertyValue ( key ) ;
16761676 }
16771677 }
16781678
@@ -1853,7 +1853,7 @@ public override void Dispose()
18531853 {
18541854 var key = await ExecuteScalarAsync < TKey > ( connection , "SELECT @@IDENTITY" , null , cancellationToken ) ;
18551855
1856- SetPrimaryKey ( entitySet . Entity , key ) ;
1856+ entitySet . Entity . SetPrimaryKeyPropertyValue ( key ) ;
18571857 }
18581858 }
18591859
0 commit comments