/// <summary> /// Constructs StandardProperty instances. /// </summary> /// <param name="name">The name by which the property can be referenced within /// its owner.</param> /// <param name="type">The Hibernate Type of this property.</param> /// <param name="lazy">Should this property be handled lazily?</param> /// <param name="insertable">Is this property an insertable value?</param> /// <param name="updateable">Is this property an updateable value?</param> /// <param name="insertGenerated">Is this property generated in the database on insert?</param> /// <param name="updateGenerated">Is this property generated in the database on update?</param> /// <param name="nullable">Is this property a nullable value?</param> /// <param name="checkable">Is this property a checkable value?</param> /// <param name="versionable">Is this property a versionable value?</param> /// <param name="cascadeStyle">The cascade style for this property's value.</param> /// <param name="fetchMode">Any fetch mode defined for this property </param> public StandardProperty( String name, IType type, bool lazy, bool insertable, bool updateable, bool insertGenerated, bool updateGenerated, bool nullable, bool checkable, bool versionable, CascadeStyle cascadeStyle, FetchMode?fetchMode) : base(name, type) { this.lazy = lazy; this.insertable = insertable; this.updateable = updateable; this.insertGenerated = insertGenerated; this.updateGenerated = updateGenerated; this.nullable = nullable; this.dirtyCheckable = checkable; this.versionable = versionable; this.cascadeStyle = cascadeStyle; this.fetchMode = fetchMode; }
/// <summary> /// Constructs an instance of <see cref="EntityAssociation"/>. /// </summary> public EntityAssociation( Type entityType, bool isOneToOne, IReadOnlyList <string> foreignKeyPropertyNames, ForeignKeyDirection foreignKeyDirection, IType identifierType, bool isChild, string inverseAssociationPropertyName, CascadeStyle inverseAssociationPropertyCascadeStyle, string associationPropertyName, CascadeStyle associationPropertyCascadeStyle, Action <object, object> addFunction, Action <object, object> removeFunction) : base(entityType, foreignKeyPropertyNames, foreignKeyDirection, true) { IsOneToOne = isOneToOne; IdentifierType = identifierType; IsChild = isChild; InverseAssociationPropertyName = inverseAssociationPropertyName; InverseAssociationPropertyCascadeStyle = inverseAssociationPropertyCascadeStyle; AssociationPropertyName = associationPropertyName; AssociationPropertyCascadeStyle = associationPropertyCascadeStyle; _addFunction = addFunction; _removeFunction = removeFunction; }
protected override JoinType GetJoinType(IAssociationType type, FetchMode config, string path, string lhsTable, string[] lhsColumns, bool nullable, int currentDepth, CascadeStyle cascadeStyle) { if (translator.IsJoin(path)) { return(translator.GetJoinType(path)); } if (translator.HasProjection) { return(JoinType.None); } var selectMode = translator.RootCriteria.GetSelectMode(path); switch (selectMode) { case SelectMode.Undefined: return(base.GetJoinType(type, config, path, lhsTable, lhsColumns, nullable, currentDepth, cascadeStyle)); case SelectMode.Fetch: case SelectMode.FetchLazyProperties: case SelectMode.ChildFetch: case SelectMode.JoinOnly: IsDuplicateAssociation(lhsTable, lhsColumns, type); //deliberately ignore return value! return(GetJoinType(nullable, currentDepth)); case SelectMode.Skip: return(JoinType.None); default: throw new ArgumentOutOfRangeException(nameof(selectMode), selectMode.ToString()); } }
/// <summary> /// Deletes the object from the database when the method SubmitChanges is called /// </summary> /// <typeparam name="T"></typeparam> /// <param name="obj"></param> /// <param name="cascade">Whether the child/parent objects will also be deleted /// Note: It's recommended to leave that kind of logic to the database engine</param> public void DeleteOnSubmit <T>(T obj, CascadeStyle cascade = CascadeStyle.None) where T : class { if (!TransactionActive) { transaction = _conn.BeginTransaction(); TransactionActive = true; } Type type = typeof(T); string tableName = GetTableName(type); string pk = "id"; object pkValue = null; foreach (PropertyInfo pi in type.GetProperties()) { bool ispk = (from a in pi.GetCustomAttributes(false) where a.GetType().Name.Equals("KeyAttribute") select a).Any(); if (ispk || pi.Name.Equals(pk, StringComparison.OrdinalIgnoreCase)) { pk = pi.Name; pkValue = pi.GetValue(obj, null); } else if (cascade != CascadeStyle.None) { if (pi.GetValue(obj, null) == null) { continue; } if ((cascade == CascadeStyle.Collection || cascade == CascadeStyle.All) && IsCollection(pi.PropertyType)) { foreach (var child in pi.GetValue(obj, null) as ICollection) { MethodInfo mi = typeof(Context).GetMethod("DeleteOnSubmit"); MethodInfo genericMethod = mi.MakeGenericMethod(new Type[] { child.GetType() }); genericMethod.Invoke(this, new Object[] { child, cascade }); } } else if ((cascade == CascadeStyle.Single || cascade == CascadeStyle.All) && !IsPrimitive(pi.PropertyType)) { MethodInfo mi = typeof(Context).GetMethod("DeleteOnSubmit"); MethodInfo genericMethod = mi.MakeGenericMethod(new Type[] { pi.PropertyType }); genericMethod.Invoke(this, new Object[] { pi.GetValue(obj, null), cascade }); } } } IDbCommand com = _conn.CreateCommand(); com.Transaction = transaction; com.CommandText = "DELETE FROM " + tableName + " WHERE [" + pk + "] = " + pkValue; com.ExecuteNonQuery(); }
private static bool IsCascaded(EntityState state, CascadeStyle cascade) { if (cascade == null || cascade == CascadeStyle.None) { return(false); } return(ValidCascadeStyles.Contains(cascade) || StateValidCascadeStyles.TryGetValue(state, out var validCascade) && validCascade == cascade); }
/// <summary> /// Constructs VersionProperty instances. /// </summary> /// <param name="name">The name by which the property can be referenced within /// its owner.</param> /// <param name="type">The Hibernate Type of this property.</param> /// <param name="lazy">Should this property be handled lazily?</param> /// <param name="insertable">Is this property an insertable value?</param> /// <param name="updateable">Is this property an updateable value?</param> /// <param name="insertGenerated">Is this property generated in the database on insert?</param> /// <param name="updateGenerated">Is this property generated in the database on update?</param> /// <param name="nullable">Is this property a nullable value?</param> /// <param name="checkable">Is this property a checkable value?</param> /// <param name="versionable">Is this property a versionable value?</param> /// <param name="cascadeStyle">The cascade style for this property's value.</param> /// <param name="unsavedValue">The value which, if found as the value of /// this (i.e., the version) property, represents new (i.e., un-saved) /// instances of the owning entity.</param> public VersionProperty( string name, IType type, bool lazy, bool insertable, bool updateable, bool insertGenerated, bool updateGenerated, bool nullable, bool checkable, bool versionable, CascadeStyle cascadeStyle, VersionValue unsavedValue) : base( name, type, lazy, insertable, updateable, insertGenerated, updateGenerated, nullable, checkable, versionable, cascadeStyle, null) { this.unsavedValue = unsavedValue; }
protected override JoinType GetJoinType(IAssociationType type, FetchMode config, string path, string lhsTable, string[] lhsColumns, bool nullable, int currentDepth, CascadeStyle cascadeStyle) { if (translator.IsJoin(path)) { return(translator.GetJoinType(path)); } else { if (translator.HasProjection) { return(JoinType.None); } else { FetchMode fetchMode = translator.RootCriteria.GetFetchMode(path); if (IsDefaultFetchMode(fetchMode)) { return(base.GetJoinType(type, config, path, lhsTable, lhsColumns, nullable, currentDepth, cascadeStyle)); } else { if (fetchMode == FetchMode.Join) { IsDuplicateAssociation(lhsTable, lhsColumns, type); //deliberately ignore return value! return(GetJoinType(nullable, currentDepth)); } else { return(JoinType.None); } } } } }
/// <summary> /// Override on subclasses to enable or suppress joining /// of certain association types /// </summary> protected virtual bool IsJoinedFetchEnabled(IAssociationType type, FetchMode config, CascadeStyle cascadeStyle) { return(type.IsEntityType && IsJoinedFetchEnabledInMapping(config, type)); }
/// <summary> /// Get the join type (inner, outer, etc) or -1 if the /// association should not be joined. Override on /// subclasses. /// </summary> protected virtual JoinType GetJoinType(IAssociationType type, FetchMode config, string path, string pathAlias, string lhsTable, string[] lhsColumns, bool nullable, int currentDepth, CascadeStyle cascadeStyle) { // 6.0 TODO: inline the call #pragma warning disable 618 return(GetJoinType(type, config, path, lhsTable, lhsColumns, nullable, currentDepth, cascadeStyle)); #pragma warning restore 618 }
protected virtual JoinType GetJoinType(IAssociationType type, FetchMode config, string path, string lhsTable, string[] lhsColumns, bool nullable, int currentDepth, CascadeStyle cascadeStyle) { if (!IsJoinedFetchEnabled(type, config, cascadeStyle)) { return(JoinType.None); } if (IsTooDeep(currentDepth) || (type.IsCollectionType && IsTooManyCollections)) { return(JoinType.None); } bool dupe = IsDuplicateAssociation(lhsTable, lhsColumns, type); if (dupe) { return(JoinType.None); } return(GetJoinType(nullable, currentDepth)); }
protected override bool IsJoinedFetchEnabled(IAssociationType type, FetchMode config, CascadeStyle cascadeStyle) { return ((type.IsEntityType || type.IsCollectionType) && (cascadeStyle == null || cascadeStyle.DoCascade(cascadeAction))); }
/// <summary> /// The superclass deliberately excludes collections /// </summary> protected override bool IsJoinedFetchEnabled(IAssociationType type, FetchMode config, CascadeStyle cascadeStyle) { return(IsJoinedFetchEnabledInMapping(config, type)); }
/// <summary> /// Disable outer join fetching if this loader obtains an /// upgrade lock mode /// </summary> protected override bool IsJoinedFetchEnabled(IAssociationType type, FetchMode config, CascadeStyle cascadeStyle) { return(lockMode.GreaterThan(LockMode.Read) ? false : base.IsJoinedFetchEnabled(type, config, cascadeStyle)); }
/// <summary> /// Updates an object on the database when the SubmitChanges method is called /// </summary> /// <typeparam name="T"></typeparam> /// <param name="obj">The object to update</param> /// <param name="cascade">Whether to update child/parent objects too</param> public void UpdateOnSubmit <T>(T obj, CascadeStyle cascade = CascadeStyle.None) where T : class { if (obj == null) { return; } if (!TransactionActive) { transaction = _conn.BeginTransaction(); TransactionActive = true; } Type type = typeof(T); string tableName = GetTableName(type); List <string> fields = new List <string>(); List <string> values = new List <string>(); List <object> data = new List <object>(); string pk = "id"; object pkValue = null; foreach (PropertyInfo pi in type.GetProperties()) { bool ispk = (from a in pi.GetCustomAttributes(false) where a.GetType().Name.Equals("KeyAttribute") select a).Any(); if (ispk || pi.Name.Equals(pk, StringComparison.OrdinalIgnoreCase)) { pk = pi.Name; pkValue = pi.GetValue(obj, null); } else { if ((cascade == CascadeStyle.All || cascade == CascadeStyle.Collection) && IsCollection(pi.PropertyType) && pi.GetValue(obj, null) != null) { foreach (var child in pi.GetValue(obj, null) as ICollection) { MethodInfo mi = typeof(Context).GetMethod("UpdateOnSubmit"); MethodInfo genericMethod = mi.MakeGenericMethod(new Type[] { child.GetType() }); genericMethod.Invoke(this, new Object[] { child, cascade }); } } else if ((cascade == CascadeStyle.All || cascade == CascadeStyle.Single) && !IsPrimitive(pi.PropertyType)) { // If it's not a primitive I'll try to insert it as a child object MethodInfo mi = typeof(Context).GetMethod("UpdateOnSubmit"); MethodInfo genericMethod = mi.MakeGenericMethod(new Type[] { pi.PropertyType }); genericMethod.Invoke(this, new Object[] { pi.GetValue(obj, null), cascade }); } else { fields.Add("[" + pi.Name + "] = @" + pi.Name); values.Add("@" + pi.Name); data.Add(pi.GetValue(obj, null)); } } } if (pkValue == null) { throw new Exception("Could not find primary key"); } IDbCommand com = _conn.CreateCommand(); com.Transaction = transaction; com.CommandText = string.Format("UPDATE {0} SET {1} WHERE {2} = {3}", tableName, string.Join(", ", fields), pk, pkValue); for (int i = 0; i < values.Count; i++) { IDbDataParameter p = com.CreateParameter(); p.ParameterName = values[i]; p.Value = data[i]; com.Parameters.Add(p); } try { com.ExecuteNonQuery(); } catch { throw; } }