/// <summary> /// Delete all entities in the table related to the type T. /// </summary> /// <typeparam name="T">Type of entity</typeparam> /// <param name="connection">Open SqlConnection</param> /// <param name="transaction">The transaction to run under, null (the default) if none</param> /// <param name="commandTimeout">Number of seconds before command execution timeout</param> /// <returns>true if deleted, false if none found</returns> public static bool DeleteAll <T>(this IDbConnection connection, IDbTransaction transaction = null, int?commandTimeout = null) where T : class { var connectionName = GetDatabaseType?.Invoke(connection).ToLower() ?? connection.GetType().Name.ToLower(); var type = typeof(T); var name = GetTableName(type); if (connectionName == "hanaconnection") { var statement = $"delete from \"{name}\""; var deleted = connection.Execute(statement, null, transaction, commandTimeout); return(deleted > 0); } else { var statement = $"delete from {name}"; var deleted = connection.Execute(statement, null, transaction, commandTimeout); return(deleted > 0); } }
/// <summary> /// Inserts an entity into table "Ts" and returns identity id or number of inserted rows if inserting a list. /// </summary> /// <typeparam name="T">The type to insert.</typeparam> /// <param name="connection">Open SqlConnection</param> /// <param name="entityToInsert">Entity to insert, can be list of entities</param> /// <param name="transaction">The transaction to run under, null (the default) if none</param> /// <param name="commandTimeout">Number of seconds before command execution timeout</param> /// <returns>Identity of inserted entity, or number of inserted rows if inserting a list</returns> public static long Insert <T>(this IDbConnection connection, T entityToInsert, IDbTransaction transaction = null, int?commandTimeout = null) where T : class { var connectionName = GetDatabaseType?.Invoke(connection).ToLower() ?? connection.GetType().Name.ToLower(); var isList = false; var type = typeof(T); if (type.IsArray) { isList = true; type = type.GetElementType(); } else if (type.IsGenericType) { var typeInfo = type.GetTypeInfo(); bool implementsGenericIEnumerableOrIsGenericIEnumerable = typeInfo.ImplementedInterfaces.Any(ti => ti.IsGenericType && ti.GetGenericTypeDefinition() == typeof(IEnumerable <>)) || typeInfo.GetGenericTypeDefinition() == typeof(IEnumerable <>); if (implementsGenericIEnumerableOrIsGenericIEnumerable) { isList = true; type = type.GetGenericArguments()[0]; } } var name = GetTableName(type); var sbColumnList = new StringBuilder(null); var allProperties = TypePropertiesCache(type); var keyProperties = KeyPropertiesCache(type); var computedProperties = ComputedPropertiesCache(type); var allPropertiesExceptKeyAndComputed = allProperties.Except(keyProperties.Union(computedProperties)).ToList(); var adapter = GetFormatter(connection); for (var i = 0; i < allPropertiesExceptKeyAndComputed.Count; i++) { var property = allPropertiesExceptKeyAndComputed[i]; adapter.AppendColumnName(sbColumnList, property.Name); //fix for issue #336 if (i < allPropertiesExceptKeyAndComputed.Count - 1) { sbColumnList.Append(", "); } } var sbParameterList = new StringBuilder(null); for (var i = 0; i < allPropertiesExceptKeyAndComputed.Count; i++) { var property = allPropertiesExceptKeyAndComputed[i]; if (connectionName == "hanaconnection") { sbParameterList.AppendFormat(":{0}", property.Name); } else { sbParameterList.AppendFormat("@{0}", property.Name); } if (i < allPropertiesExceptKeyAndComputed.Count - 1) { sbParameterList.Append(", "); } } int returnVal; var wasClosed = connection.State == ConnectionState.Closed; if (wasClosed) { connection.Open(); } if (!isList) //single entity { returnVal = adapter.Insert(connection, transaction, commandTimeout, name, sbColumnList.ToString(), sbParameterList.ToString(), keyProperties, entityToInsert); } else { //insert list of entities if (connectionName == "hanaconnection") { var cmd = $"insert into \"{name}\" ({sbColumnList}) values ({sbParameterList})"; returnVal = connection.Execute(cmd, entityToInsert, transaction, commandTimeout); } else { var cmd = $"insert into {name} ({sbColumnList}) values ({sbParameterList})"; returnVal = connection.Execute(cmd, entityToInsert, transaction, commandTimeout); } } if (wasClosed) { connection.Close(); } return(returnVal); }
/// <summary> /// Delete entity in table "Ts". /// </summary> /// <typeparam name="T">Type of entity</typeparam> /// <param name="connection">Open SqlConnection</param> /// <param name="entityToDelete">Entity to delete</param> /// <param name="transaction">The transaction to run under, null (the default) if none</param> /// <param name="commandTimeout">Number of seconds before command execution timeout</param> /// <returns>true if deleted, false if not found</returns> public static bool Delete <T>(this IDbConnection connection, T entityToDelete, IDbTransaction transaction = null, int?commandTimeout = null) where T : class { var connectionName = GetDatabaseType?.Invoke(connection).ToLower() ?? connection.GetType().Name.ToLower(); if (entityToDelete == null) { throw new ArgumentException("Cannot Delete null Object", nameof(entityToDelete)); } var type = typeof(T); if (type.IsArray) { type = type.GetElementType(); } else if (type.IsGenericType) { var typeInfo = type.GetTypeInfo(); bool implementsGenericIEnumerableOrIsGenericIEnumerable = typeInfo.ImplementedInterfaces.Any(ti => ti.IsGenericType && ti.GetGenericTypeDefinition() == typeof(IEnumerable <>)) || typeInfo.GetGenericTypeDefinition() == typeof(IEnumerable <>); if (implementsGenericIEnumerableOrIsGenericIEnumerable) { type = type.GetGenericArguments()[0]; } } var keyProperties = KeyPropertiesCache(type).ToList(); //added ToList() due to issue #418, must work on a list copy var explicitKeyProperties = ExplicitKeyPropertiesCache(type); if (keyProperties.Count == 0 && explicitKeyProperties.Count == 0) { throw new ArgumentException("Entity must have at least one [Key] or [ExplicitKey] property"); } var name = GetTableName(type); keyProperties.AddRange(explicitKeyProperties); var sb = new StringBuilder(); if (connectionName == "hanaconnection") { sb.AppendFormat("delete from \"{0}\" where ", name); } else { sb.AppendFormat("delete from {0} where ", name); } var adapter = GetFormatter(connection); for (var i = 0; i < keyProperties.Count; i++) { var property = keyProperties[i]; adapter.AppendColumnNameEqualsValue(sb, property.Name); //fix for issue #336 if (i < keyProperties.Count - 1) { sb.Append(" and "); } } var deleted = connection.Execute(sb.ToString(), entityToDelete, transaction, commandTimeout); return(deleted > 0); }
/// <summary> /// Returns a single entity by a single id from table "Ts". /// Id must be marked with [Key] attribute. /// Entities created from interfaces are tracked/intercepted for changes and used by the Update() extension /// for optimal performance. /// </summary> /// <typeparam name="T">Interface or type to create and populate</typeparam> /// <param name="connection">Open SqlConnection</param> /// <param name="id">Id of the entity to get, must be marked with [Key] attribute</param> /// <param name="transaction">The transaction to run under, null (the default) if none</param> /// <param name="commandTimeout">Number of seconds before command execution timeout</param> /// <returns>Entity of T</returns> public static T Get <T>(this IDbConnection connection, dynamic id, IDbTransaction transaction = null, int?commandTimeout = null) where T : class { var type = typeof(T); var connectionName = GetDatabaseType?.Invoke(connection).ToLower() ?? connection.GetType().Name.ToLower(); if (!GetQueries.TryGetValue(type.TypeHandle, out string sql)) { var key = GetSingleKey <T>(nameof(Get)); var name = GetTableName(type); if (connectionName == "hanaconnection") { sql = $"select * from \"{name}\" where \"{key.Name}\" = :id"; } else { sql = $"select * from \"{name}\" where \"{key.Name}\" = :id"; } GetQueries[type.TypeHandle] = sql; } var dynParms = new DynamicParameters(); if (connectionName == "hanaconnection") { dynParms.Add(":id", id); } else { dynParms.Add("@id", id); } T obj; if (type.IsInterface) { var res = connection.Query(sql, dynParms).FirstOrDefault() as IDictionary <string, object>; if (res == null) { return(null); } obj = ProxyGenerator.GetInterfaceProxy <T>(); foreach (var property in TypePropertiesCache(type)) { var val = res[property.Name]; if (val == null) { continue; } if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable <>)) { var genericType = Nullable.GetUnderlyingType(property.PropertyType); if (genericType != null) { property.SetValue(obj, Convert.ChangeType(val, genericType), null); } } else { property.SetValue(obj, Convert.ChangeType(val, property.PropertyType), null); } } ((IProxy)obj).IsDirty = false; //reset change tracking and return } else { obj = connection.Query <T>(sql, dynParms, transaction, commandTimeout: commandTimeout).FirstOrDefault(); } return(obj); }