@@ -1023,6 +1023,141 @@ private bool TryLoadEntities<T>(string table, ICollection<KeyValuePair<string, o
10231023 }
10241024 #endregion Load Methods
10251025
1026+ #region Delete
1027+
1028+ /// <summary>
1029+ /// Deletes an entity from the database.
1030+ /// </summary>
1031+ /// <param name="entity">The entity to delete.</param>
1032+ /// <param name="table">The name of the table to delete from.</param>
1033+ /// <param name="identityColumns">Must contain the columns that identify the entity (Case sensitive).</param>
1034+ /// <returns>Returns true if successful, else false.</returns>
1035+ public bool DeleteEntity < T > ( T entity , string tableName , string [ ] identityColumns ) where T : class
1036+ {
1037+ return DeleteEntitiesFromList ( new List < T > { entity } , tableName , identityColumns ) ;
1038+ }
1039+
1040+ /// <summary>
1041+ /// Deletes a list of entities from the database.
1042+ /// </summary>
1043+ /// <param name="entityList">List of entities to delete.</param>
1044+ /// <param name="table">The name of the table to delete from.</param>
1045+ /// <param name="identityColumns">Must contain the columns that identify the entity (Case sensitive).</param>
1046+ /// <returns>Returns true if successful, else false. If an entity fails, the rest of the list will not be deleted.</returns>
1047+ public bool DeleteEntities < T > ( List < T > entityList , string tableName , string [ ] identityColumns ) where T : class
1048+ {
1049+ return DeleteEntitiesFromList ( entityList , tableName , identityColumns ) ;
1050+ }
1051+
1052+ /// <summary>
1053+ /// Deletes from a table using conditions.
1054+ /// </summary>
1055+ /// <param name="table">The name of the table to delete from.</param>
1056+ /// <param name="filterDictionary">Search filters. Each entry in the Dictionary contains:
1057+ /// Key: SQL string, ie. 'id > @id', 'birth = @birth' or 'name like '%br%' '.
1058+ /// Value: The object to replace @. If it's null, it will not be added to parameters there should not be a @ in the key.
1059+ /// Filter may be null if no search criteria!</param>
1060+ /// <param name="affectedRows">The number of deleted rows.</param>
1061+ /// <returns>True if the query succeeded - no matter if anything was deleted.</returns>
1062+ public bool DeleteViaConditions ( string tableName , Dictionary < string , object > filterDictionary , out int affectedRows )
1063+ {
1064+ affectedRows = 0 ;
1065+
1066+ try
1067+ {
1068+ SqlCommand cmd = GetSqlCommand ( ) ;
1069+ string sqlDelete = "DELETE FROM [" + tableName + "] WHERE " ;
1070+ if ( filterDictionary != null && filterDictionary . Count > 0 )
1071+ {
1072+ int i = 0 ;
1073+ foreach ( KeyValuePair < string , object > pair in filterDictionary )
1074+ {
1075+
1076+ sqlDelete += pair . Key + " AND " ;
1077+ if ( pair . Value != null )
1078+ {
1079+ AddParameterToCmd ( pair . Value , cmd , "" + i ++ ) ;
1080+ }
1081+ }
1082+ }
1083+ else
1084+ {
1085+ sqlDelete = sqlDelete . Substring ( 0 , sqlDelete . Length - 2 ) ;
1086+ }
1087+ cmd . CommandText = sqlDelete . Substring ( 0 , sqlDelete . Length - 4 ) ;
1088+ affectedRows = cmd . ExecuteNonQuery ( ) ;
1089+ return true ;
1090+ }
1091+ catch ( Exception ex )
1092+ {
1093+ string message = "" ;
1094+ message += "Table name: " + tableName + Environment . NewLine ;
1095+ if ( filterDictionary != null && filterDictionary . Count != 0 )
1096+ {
1097+ message += "Filter: " + Environment . NewLine ;
1098+ foreach ( KeyValuePair < string , object > pair in filterDictionary )
1099+ {
1100+ message += "\t Key: " + pair . Key + "\t Value: " + pair . Value + Environment . NewLine ;
1101+ }
1102+ }
1103+ message += "Error message: " + ex . Message + Environment . NewLine ;
1104+ message += "Stacktrace: " + ex . StackTrace + Environment . NewLine ;
1105+
1106+ Debug . WriteLine ( message ) ;
1107+ if ( ErrorOccurred != null )
1108+ ErrorOccurred ( ex ) ;
1109+ return false ;
1110+ }
1111+ }
1112+
1113+ private bool DeleteEntitiesFromList < T > ( List < T > entityList , string tableName , IEnumerable < string > identityColumns ) where T : class
1114+ {
1115+ Type entityType = null ;
1116+ try
1117+ {
1118+ if ( entityList . Count == 0 ) // no entities... returns true
1119+ return true ;
1120+
1121+ SqlCommand cmd = GetSqlCommand ( ) ;
1122+ entityType = entityList [ 0 ] . GetType ( ) ;
1123+
1124+ // - generate the SQL
1125+ cmd . Parameters . Clear ( ) ;
1126+ cmd . CommandText = "DELETE FROM [" + tableName + "] WHERE " ;
1127+ foreach ( string idColumn in identityColumns )
1128+ {
1129+ cmd . CommandText += idColumn + " = @" + idColumn + " AND " ;
1130+ }
1131+ cmd . CommandText = cmd . CommandText . Substring ( 0 , cmd . CommandText . Length - 4 ) ;
1132+
1133+ foreach ( T entity in entityList )
1134+ {
1135+ cmd . Parameters . Clear ( ) ;
1136+ foreach ( string idColumn in identityColumns ) // add parameters for each entitys identity columns
1137+ {
1138+ PropertyInfo propertyInfo = entityType . GetProperty ( idColumn ) ;
1139+ object fieldObj = propertyInfo . GetValue ( entity , null ) ;
1140+ AddParameterToCmd ( fieldObj , cmd , idColumn ) ;
1141+ }
1142+ int affectedRows = cmd . ExecuteNonQuery ( ) ;
1143+ if ( affectedRows == 0 ) // error - nothing deleted
1144+ return false ;
1145+ }
1146+ }
1147+ catch ( Exception exception )
1148+ {
1149+ string errorMessage = GenerateErrorMessage < T > ( entityList . Count > 0 ? entityList [ 0 ] . GetType ( ) : null , tableName , exception . Message ,
1150+ exception . StackTrace ) ;
1151+
1152+ Debug . WriteLine ( errorMessage ) ;
1153+ ErrorOccurred ? . Invoke ( exception ) ;
1154+ return false ;
1155+ }
1156+ return true ;
1157+ }
1158+
1159+ #endregion Delete
1160+
10261161
10271162 #region Helper Methods
10281163
@@ -1039,6 +1174,19 @@ private string GenerateErrorMessage<T>(Type entityType, string table, SaveType s
10391174 return message ;
10401175 }
10411176
1177+ private string GenerateErrorMessage < T > ( Type entityType , string table , string exceptionMessage , string stacktrace ) where T : class
1178+ {
1179+ string message = "" ;
1180+ message += "Entity type: " + entityType ?? "NULL" + Environment . NewLine ;
1181+
1182+ message += "Table name: " + table + Environment . NewLine ;
1183+ message += "Save type: " + "DELETE" + Environment . NewLine ;
1184+ message += "Error message: " + exceptionMessage + Environment . NewLine ;
1185+ message += "Stacktrace: " + stacktrace + Environment . NewLine ;
1186+
1187+ return message ;
1188+ }
1189+
10421190 private SqlCommand GetSqlCommand ( )
10431191 {
10441192 SqlCommand sqlCommand ;
@@ -1108,6 +1256,21 @@ public Dictionary<string, string> GetTableColumns(SqlCommand cmd, string table,
11081256 return tableColumns ;
11091257 }
11101258
1259+ public Dictionary < string , string > GetTableColumns ( SqlDataReader reader )
1260+ {
1261+ Dictionary < string , string > tableColumns = new Dictionary < string , string > ( ) ;
1262+ DataTable dataTable = reader . GetSchemaTable ( ) ;
1263+ // Put the column names in list, to make them easier to work with
1264+ if ( dataTable != null )
1265+ {
1266+ foreach ( DataRow row in dataTable . Rows )
1267+ {
1268+ tableColumns [ ( row [ "ColumnName" ] + "" ) . ToLower ( ) ] = "" + row [ "DataType" ] ;
1269+ }
1270+ }
1271+ return tableColumns ;
1272+ }
1273+
11111274 private void AddParameterToCmd ( object fieldObj , SqlCommand cmd , string idColumn )
11121275 {
11131276 cmd . Parameters . AddWithValue ( "@" + idColumn , fieldObj ?? DBNull . Value ) ;
0 commit comments