protected void FillLazyObjectRelations(DataObject dataObject, bool autoload) { try { var dataObjectType = dataObject.GetType(); MemberInfo[] myMembers; if (!MemberInfoCache.TryGetValue(dataObjectType, out myMembers)) { myMembers = dataObjectType.GetMembers(); MemberInfoCache[dataObjectType] = myMembers; } for (int i = 0; i < myMembers.Length; i++) { Relation[] myAttributes = GetRelationAttributes(myMembers[i]); if (myAttributes.Length > 0) { Relation rel = myAttributes[0]; if ((rel.AutoLoad == false) && autoload) { continue; } bool isArray = false; Type remoteType; DataObject[] elements; string local = rel.LocalField; string remote = rel.RemoteField; if (myMembers[i] is PropertyInfo) { remoteType = ((PropertyInfo)myMembers[i]).PropertyType; } else { remoteType = ((FieldInfo)myMembers[i]).FieldType; } if (remoteType.HasElementType) { remoteType = remoteType.GetElementType(); isArray = true; } PropertyInfo prop = dataObjectType.GetProperty(local); FieldInfo field = dataObjectType.GetField(local); object val = 0; if (prop != null) { val = prop.GetValue(dataObject, null); } if (field != null) { val = field.GetValue(dataObject); } if (val != null && val.ToString() != string.Empty) { if (DataObject.GetPreCachedFlag(remoteType)) { elements = new DataObject[1]; elements[0] = FindObjectByKeyImpl(remoteType, val); } else { elements = SelectObjectsImpl(remoteType, remote + " = '" + Escape(val.ToString()) + "'", Transaction.IsolationLevel.DEFAULT); } if ((elements != null) && (elements.Length > 0)) { if (isArray) { if (myMembers[i] is PropertyInfo) { ((PropertyInfo)myMembers[i]).SetValue(dataObject, elements, null); } if (myMembers[i] is FieldInfo) { var currentField = (FieldInfo)myMembers[i]; ConstructorInfo constructor; if (!ConstructorByFieldType.TryGetValue(currentField.FieldType, out constructor)) { constructor = currentField.FieldType.GetConstructor(new[] { typeof(int) }); ConstructorByFieldType[currentField.FieldType] = constructor; } object elementHolder = constructor.Invoke(new object[] { elements.Length }); var elementArray = (object[])elementHolder; for (int m = 0; m < elementArray.Length; m++) { elementArray[m] = elements[m]; } currentField.SetValue(dataObject, elementArray); } } else { if (myMembers[i] is PropertyInfo) { ((PropertyInfo)myMembers[i]).SetValue(dataObject, elements[0], null); } if (myMembers[i] is FieldInfo) { ((FieldInfo)myMembers[i]).SetValue(dataObject, elements[0]); } } } } } } } catch (Exception e) { throw new DatabaseException("Resolving Relations for " + dataObject.TableName + " failed!", e); } }
public void RegisterDataObject(Type objType) { if (TableDatasets.ContainsKey(GetTableOrViewName(objType))) { return; } bool primaryKeySpecified = false; bool useAutoIncrementColumn = false; bool relations = false; MemberInfo primaryIndexMember = null; string tableName = GetTableOrViewName(objType); var ds = new DataSet(); var table = new DataTable(tableName); MemberInfo[] myMembers = objType.GetMembers(); for (int i = 0; i < myMembers.Length; i++) { //object[] myAttributes = myMembers[i].GetCustomAttributes(true); //object[] myAttributes = myMembers[i].GetCustomAttributes(typeof(DOL.Database.Attributes.DataElement), true); object[] myAttributes = myMembers[i].GetCustomAttributes(typeof(PrimaryKey), true); if (myAttributes.Length > 0) { primaryKeySpecified = true; if (myMembers[i] is PropertyInfo) { table.Columns.Add(myMembers[i].Name, ((PropertyInfo)myMembers[i]).PropertyType); } else { table.Columns.Add(myMembers[i].Name, ((FieldInfo)myMembers[i]).FieldType); } table.Columns[myMembers[i].Name].AutoIncrement = ((PrimaryKey)myAttributes[0]).AutoIncrement; useAutoIncrementColumn = table.Columns[myMembers[i].Name].AutoIncrement; var index = new DataColumn[1]; index[0] = table.Columns[myMembers[i].Name]; primaryIndexMember = myMembers[i]; table.PrimaryKey = index; continue; } myAttributes = myMembers[i].GetCustomAttributes(typeof(DataElement), true); if (myAttributes.Length > 0) { //if(myAttributes[0] is Attributes.DataElement) //{ if (myMembers[i] is PropertyInfo) { table.Columns.Add(myMembers[i].Name, ((PropertyInfo)myMembers[i]).PropertyType); } else { table.Columns.Add(myMembers[i].Name, ((FieldInfo)myMembers[i]).FieldType); } table.Columns[myMembers[i].Name].AllowDBNull = ((DataElement)myAttributes[0]).AllowDbNull; if (((DataElement)myAttributes[0]).Unique) { table.Constraints.Add(new UniqueConstraint("UNIQUE_" + myMembers[i].Name, table.Columns[myMembers[i].Name])); } if (((DataElement)myAttributes[0]).IndexColumns != string.Empty) { table.Columns[myMembers[i].Name].ExtendedProperties.Add("INDEX", true); table.Columns[myMembers[i].Name].ExtendedProperties.Add("INDEXCOLUMNS", ((DataElement)myAttributes[0]).IndexColumns); } else if (((DataElement)myAttributes[0]).Index) { table.Columns[myMembers[i].Name].ExtendedProperties.Add("INDEX", true); } if (((DataElement)myAttributes[0]).Varchar > 0) { table.Columns[myMembers[i].Name].ExtendedProperties.Add("VARCHAR", ((DataElement)myAttributes[0]).Varchar); } //if(myAttributes[0] is Attributes.PrimaryKey) myAttributes = GetRelationAttributes(myMembers[i]); //if(myAttributes[0] is Attributes.Relation) if (myAttributes.Length > 0) { relations = true; } } } if (useAutoIncrementColumn == false) { // We define the Tablename_ID column that will always contain a generated unique ID DataColumn idColumn = table.Columns.Add(tableName + "_ID", typeof(string)); if (primaryKeySpecified) { // if another primary key is defined on this table but the TableName_ID column is still being used then force // the creation of a unique index on the the TableName_ID column table.Constraints.Add(new UniqueConstraint(idColumn.ColumnName, idColumn)); } } if (primaryKeySpecified == false) { var index = new DataColumn[1]; index[0] = table.Columns[tableName + "_ID"]; table.PrimaryKey = index; } if (Connection.IsSQLConnection) { Connection.CheckOrCreateTable(table); } ds.DataSetName = tableName; ds.EnforceConstraints = true; ds.CaseSensitive = false; ds.Tables.Add(table); var dth = new DataTableHandler(ds); dth.HasRelations = relations; dth.UsesPreCaching = DataObject.GetPreCachedFlag(objType); TableDatasets.Add(tableName, dth); //if (dth.UsesPreCaching && Connection.IsSQLConnection) //{ // // not useful for xml connection // if (Log.IsDebugEnabled) // Log.Debug("Precaching of " + table.TableName + "..."); // var objects = SQLSelectObjects<TObject>(""); // object key; // for (int i = 0; i < objects.Length; i++) // { // key = null; // if (primaryIndexMember == null) // { // key = objects[i].ObjectId; // } // else // { // if (primaryIndexMember is PropertyInfo) // { // key = ((PropertyInfo) primaryIndexMember).GetValue(objects[i], null); // } // else if (primaryIndexMember is FieldInfo) // { // key = ((FieldInfo) primaryIndexMember).GetValue(objects[i]); // } // } // if (key != null) // { // dth.SetPreCachedObject(key, objects[i]); // } // else // { // if (Log.IsErrorEnabled) // Log.Error("Primary key is null! " + ((primaryIndexMember != null) ? primaryIndexMember.Name : "")); // } // } // if (Log.IsDebugEnabled) // Log.Debug("Precaching of " + table.TableName + " finished!"); //} }