/// <summary> /// Given the class mapping and the column name, determines the appropriate /// c# data type. /// </summary> /// <param name="col">Column to look up.</param> /// <param name="mapping">Mapping for the class we're creating a table for.</param> /// <returns>A C# type that will be stored in the column.</returns> protected Type GetDataType(string col, ClassMapping mapping) { Type colType = null; // Use the explicit type if there is one. if (mapping.DataColTypesByDataCol.ContainsKey(col)) { colType = mapping.DataColTypesByDataCol[col]; } // Otherwise use the type of the member on the mapped object. if ((colType == null) && (mapping.AllObjMemberInfosByDataCol.ContainsKey(col))) { MemberInfo info = mapping.AllObjMemberInfosByDataCol[col]; if (info is FieldInfo) { colType = ((FieldInfo)info).FieldType; } else if (info is PropertyInfo) { colType = ((PropertyInfo)info).PropertyType; } } // Default behavior is assume string since pretty much everything can be stored // as a string. This should generally only happen for DictionaryDAOs. if (colType == null) { colType = typeof(string); } return colType; }
/// <summary> /// Updates a data object record using the "table" and a list of column/value pairs. /// </summary> /// <param name="transaction">The transaction to do this as part of.</param> /// <param name="mapping">The mapping of the table or other data container we're dealing with.</param> /// <param name="crit">All records matching this criteria will be updated per the dictionary of /// values.</param> /// <param name="propValues">A dictionary of column/value pairs for all non-ID columns to be updated.</param> /// <returns>The number of records affected.</returns> public abstract int Update(ITransaction transaction, ClassMapping mapping, DaoCriteria crit, IDictionary<string, object> propValues);
/// <summary> /// Updates a list of data object records of the same type. The default implementation /// merely calls Update for each one, however some datasources may have more efficient /// ways of inserting multiple records that the appropriate DaLayer will take advantage of. /// </summary> /// <param name="transaction">The transaction to do this as part of.</param> /// <param name="mapping">The mapping of the table or other data container we're dealing with.</param> /// <param name="criteriaList">A list of DaoCriteria. /// Each item in the list should represent the criteria for /// rows that will be updated per the accompanying dictionary.</param> /// <param name="propValueDictionaries">A list of dictionaries of column/value pairs. /// Each item in the list should represent the dictionary of non-ID column/value pairs for /// each respective object being updated.</param> public virtual void UpdateBatch(ITransaction transaction, ClassMapping mapping, List<DaoCriteria> criteriaList, List<IDictionary<string, object>> propValueDictionaries) { for (int i = 0; i < criteriaList.Count; i++) { Update(transaction, mapping, criteriaList[i], propValueDictionaries[i]); } }
/// <summary> /// Inserts a list of data object records of the same type. The default implementation /// merely calls Insert for each one, however some datasources may have more efficient /// ways of inserting multiple records that the appropriate DaLayer will take advantage of. /// </summary> /// <param name="transaction">The transaction to do this as part of.</param> /// <param name="mapping">The mapping of the table or other data container we're dealing with.</param> /// <param name="propValueDictionaries">A list of dictionaries of column/value pairs. /// Each item in the list should represent the dictionary of column/value pairs for /// each respective object being inserted.</param> public virtual void InsertBatch(ITransaction transaction, ClassMapping mapping, List<IDictionary<string, object>> propValueDictionaries) { foreach(Dictionary<string, object> propValues in propValueDictionaries) { Insert(transaction, mapping, propValues); } }
/// <summary> /// Deletes all contents of the table. Faster for large tables than DeleteAll, /// but requires greater permissions. For layers that do not support this, the /// behavior should be the same as calling Delete(null, mapping). /// </summary> public abstract void Truncate(ClassMapping mapping);
/// <summary> /// Finds the last generated id number for a column. /// </summary> /// <param name="transaction">The transaction to do this as part of.</param> /// <param name="mapping">The class mapping for the table being queried.</param> /// <param name="idCol">The ID column for which to find the last-generated ID.</param> public abstract object GetLastAutoGeneratedId(ITransaction transaction, ClassMapping mapping, string idCol);
/// <summary> /// Inserts a data object record using the "table" and a list of column/value pairs. /// </summary> /// <param name="transaction">The transaction to do this as part of.</param> /// <param name="mapping">The mapping of the table or other data container we're dealing with.</param> /// <param name="propValues">A dictionary of "column"/value pairs for the object to insert.</param> /// <returns>The number of records affected.</returns> public abstract int Insert(ITransaction transaction, ClassMapping mapping, IDictionary<string, object> propValues);
/// <summary> /// Gets a count of records for the given criteria, /// aggregated by the given grouping expressions. This matches "GROUP BY" behavior /// in SQL. /// </summary> /// <param name="transaction">The transaction to do this as part of.</param> /// <param name="mapping">The mapping of the table for which to build the query string.</param> /// <param name="crit">The criteria to use for "where" comparisons.</param> /// <param name="groupExpressions">The fields/expressions to aggregate on when counting.</param> /// <returns>The number of objects that match the criteria, plus the values of those objects /// for the fields that were aggregated on.</returns> public abstract List<GroupCountResult> GetCount(ITransaction transaction, ClassMapping mapping, DaoCriteria crit, ICollection<AbstractGroupExpression> groupExpressions);
/// <summary> /// Gets a count of records for the given criteria. /// </summary> /// <param name="transaction">The transaction to do this as part of.</param> /// <param name="mapping">The mapping of the table for which to build the query string.</param> /// <param name="crit">The criteria to use for "where" comparisons.</param> /// <returns>The number of results found that matched the criteria.</returns> public abstract int GetCount(ITransaction transaction, ClassMapping mapping, DaoCriteria crit);
/// <summary> /// Executes a query and invokes a method with a DataReader of results. /// </summary> /// <param name="transaction">The transaction to do this as part of.</param> /// <param name="mapping">Class mapping for the table we're querying against. Optional, /// but not all columns may be properly typed if it is null.</param> /// <param name="query">The query to execute, should have come from CreateQuery.</param> /// <param name="invokeMe">The method to invoke with the IDataReader results.</param> /// <param name="parameters">A hashtable containing any values that need to be persisted through invoked method. /// The list of objects from the query will be placed here.</param> public abstract void ExecuteQuery(ITransaction transaction, ClassMapping mapping, IDaQuery query, DataReaderDelegate invokeMe, Hashtable parameters);
/// <summary> /// Deletes a data object record using the mapping and criteria for what's deleted. /// </summary> /// <param name="transaction">The transaction to do this as part of.</param> /// <param name="mapping">The mapping of the table from which to delete.</param> /// <param name="crit">Criteria for deletion. NOTE: Only the expressions are observed, /// other things (like "order" or start / limit) are ignored. /// WARNING: A null or empty (no expression) criteria will /// delete ALL records!</param> /// <returns>The number of records affected.</returns> public abstract int Delete(ITransaction transaction, ClassMapping mapping, DaoCriteria crit);
/// <summary> /// Builds the query based on a serializable criteria. The Query object is particular to /// the implementation, but may contain things like the parameters parsed out, or whatever /// makes sense to this FastDaoLayer. You can think of this method as a method to convert /// from the generic DaoCriteria into the specific details necessary for querying. /// </summary> /// <param name="mapping">The mapping of the table for which to build the query string.</param> /// <param name="crit">The criteria to use to find the desired objects.</param> /// <returns>A query that can be run by ExecureQuery.</returns> public abstract IDaQuery CreateQuery(ClassMapping mapping, DaoCriteria crit);