コード例 #1
0
        public void CheckMappings()
        {
            Hashtable classMappings = new Hashtable(this.mapping.Classes.Count);

            foreach (NDO.Mapping.Class cl in this.mapping.Classes)
            {
                classMappings.Add(cl.TableName, cl);
            }
            foreach (TableNode tn in databaseNode.Nodes)
            {
                NDO.Mapping.Class cl = classMappings[tn.Table.Name] as NDO.Mapping.Class;
                if (cl != null)
                {
                    tn.Table.Namespace = GetClassNamespace(cl.FullName);
                    tn.Table.ClassName = GetClassShortName(cl.FullName);
                    if (cl.Oid.IsDual)
                    {
                        MapIntermediateClass(tn, cl);
                    }
                    else
                    {
                        MapClass(tn, cl);
                    }
                    CheckFields(tn, cl);
                    CheckRelations(tn, cl);
                }
            }
        }
コード例 #2
0
 public QueryContextGenerator(Class resultClass, IList names, Mappings mappings)
 {
     this.resultClass   = resultClass;
     this.names         = names;
     this.mappings      = mappings;
     this.queryContexts = new ArrayList();
     this.allRelations  = new Hashtable(names.Count);
 }
コード例 #3
0
 void MapIntermediateClass(TableNode tn, NDO.Mapping.Class cl)
 {
     if (tn.Table.PrimaryKey == "")
     {
         tn.Table.PrimaryKey = cl.Oid.ColumnName;
     }
     //TODO: Intermediate class berücksichtigen
     tn.MapClass(null, EventArgs.Empty);
 }
コード例 #4
0
ファイル: SchemaGenerator.cs プロジェクト: mirkomaty/NDO
        private void GenerateMappingTable(NDO.Mapping.Class parentClass, NDO.Mapping.Class relClass, NDO.Mapping.Relation r, DataTable parentTable)
        {
            //MM 6 ggf. Tabelle anlegen
            //    Gibt's die Table schon in dsSchema?
            //    Nein: Anlegen
            DataTable dtMap = dsSchema.Tables[r.MappingTable.TableName];

            if (null == dtMap)
            {
                dsSchema.Tables.Add(dtMap = new DataTable(r.MappingTable.TableName));
            }

            //MM 7 ForeignKey-Spalten für eigene und Fremdklasse anlegen
            //MM 7 Wenn nötig auch die TypeColumns anlegen
            //    Addiere die Spalte r.ForeignKeyColumnName, Typ der Spalte: parentClass.Oid.ColumnType bzw. int
            new ForeignKeyIterator(r).Iterate(delegate(ForeignKeyColumn fkColumn, bool isLastElement)
            {
                searchAndAddColumn(dtMap, fkColumn.Name, null, fkColumn.SystemType);
            });

            //	Lege ggf. die Typspalte an, Typ ist immer int
            if (r.ForeignKeyTypeColumnName != null)
            {
                searchAndAddColumn(dtMap, r.ForeignKeyTypeColumnName, null, typeof(int));
            }

            new ForeignKeyIterator(r.MappingTable).Iterate(delegate(ForeignKeyColumn fkColumn, bool isLastElement)
            {
                searchAndAddColumn(dtMap, fkColumn.Name, null, fkColumn.SystemType);
            });

#if nix // Single oid column code
            // Addiere die Spalte r.MappingTable.ChildForeignKeyColumnName
            // Typ der Spalte muss ermittelt werden:
            // - Oid.FieldType
            // - [NDOObjectId] für Interfaces
            string typeName    = null;
            Type   defaultType = null;

            //TODO: Interfaces berücksichtigen
            if (relClass == null)              // Interface
            {
                // Typ ist Interface
                throw new NotImplementedException("Interface");
            }
            else
            {
                defaultType = relClass.Oid.FieldType;
            }
#endif
            if (r.MappingTable.ChildForeignKeyTypeColumnName != null)
            {
                searchAndAddColumn(dtMap, r.MappingTable.ChildForeignKeyTypeColumnName, null, typeof(int));
            }
        }
コード例 #5
0
ファイル: SchemaGenerator.cs プロジェクト: mirkomaty/NDO
        private void GenerateMappingTable(NDO.Mapping.Class parentClass, NDO.Mapping.Class relClass, NDO.Mapping.Relation r, DataTable parentTable)
        {
            //MM 6 ggf. Tabelle anlegen
            //    Gibt's die Table schon in dsSchema?
            //    Nein: Anlegen
            DataTable dtMap;

            if (!dsSchema.Tables.Contains(r.MappingTable.TableName))
            {
                dsSchema.Tables.Add(dtMap = new DataTable(r.MappingTable.TableName));
            }
            else
            {
                dtMap = dsSchema.Tables[r.MappingTable.TableName];
            }

            //MM 7 ForeignKey-Spalten für eigene und Fremdklasse anlegen
            //MM 7 Wenn nötig auch die TypeColumns anlegen
            //    Addiere die Spalte r.ForeignKeyColumnName
            new ForeignKeyIterator(r).Iterate(delegate(ForeignKeyColumn fkColumn, bool isLastElement)
            {
                SearchAndAddColumn(dtMap, fkColumn.Name, fkColumn.SystemType);
            });
            //	Lege ggf. die Typspalte an, Typ ist immer int
            if (r.ForeignKeyTypeColumnName != null)
            {
                SearchAndAddColumn(dtMap, r.ForeignKeyTypeColumnName, typeof(int));
            }

            // Addiere die Spalte r.MappingTable.ChildForeignKeyColumnName
            new ForeignKeyIterator(r.MappingTable).Iterate(delegate(ForeignKeyColumn fkColumn, bool isLastElement)
            {
                SearchAndAddColumn(dtMap, fkColumn.Name, fkColumn.SystemType);
            });
#if nix  // Old single column code
            Type defaultType = null;

            //TODO: Interfaces berücksichtigen
            if (relClass == null)              // Interface
            {
                // Typ ist Interface
                throw new NotImplementedException("Interface");
            }
            else
            {
                defaultType = relClass.Oid.FieldType;
            }
            searchAndAddColumn(dtMap, r.MappingTable.ChildForeignKeyColumnName, defaultType);
#endif
            if (r.MappingTable.ChildForeignKeyTypeColumnName != null)
            {
                SearchAndAddColumn(dtMap, r.MappingTable.ChildForeignKeyTypeColumnName, typeof(int));
            }
        }
コード例 #6
0
ファイル: SchemaGenerator.cs プロジェクト: mirkomaty/NDO
//		ArrayList baseNames = null;

        public void GenerateRelations()
        {
            DataTable dt = dsSchema.Tables[c.TableName];

            if (null == dt)
            {
                throw new InternalException(36, String.Format("Schemagenerator: GenerateRelations: DataTable {0} not found.", c.TableName));
            }

            foreach (Relation r in c.Relations)
            {
                try
                {
                    //TODO: Checken, ob man hier nicht abbrechen muss
//				if ((r.AllowSubclasses) != 0)
//					continue;

                    string rname = r.FieldName;

                    if (r.MappingTable != null)
                    {
                        continue;
                    }

                    NDO.Mapping.Class refClass = this.mappings.FindClass(r.ReferencedTypeName);
                    if (null == refClass)
                    {
                        throw new InternalException(51, String.Format("SchemaGenerator: Reference Class {0} not found", r.ReferencedTypeName));
                    }

                    // Kann keine Relation zu einer abstrakten Klasse herstellen,
                    // da diese keine Tabelle hat
                    if (refClass.IsAbstract)
                    {
                        continue;
                    }

                    //MM 5.2 Relationen anlegen
                    // Zwei gegenläufige 1:1-Beziehungen benötigen zwei Relationen
                    DataColumn parentCol;
                    DataColumn childCol;
                    DataTable  foreignTable = dsSchema.Tables[refClass.TableName];
                    if (foreignTable == null)
                    {
                        throw new InternalException(64, String.Format("SchemaGenerator: GenerateRelations: foreign Table {0} for class {1} not found.", refClass.TableName, refClass.FullName));
                    }

                    string relName;
                    if (r.Multiplicity == RelationMultiplicity.Element && GegenRelationIs1To1(r))
                    {
                        relName = dt.TableName + refClass.TableName + r.RelationName;
                    }
                    else
                    {
                        if (refClass.TableName.CompareTo(dt.TableName) < 0)
                        {
                            relName = refClass.TableName + dt.TableName + r.RelationName;
                        }
                        else
                        {
                            relName = dt.TableName + refClass.TableName + r.RelationName;
                        }
                    }

                    int colIndex = 0;
#if DEBUG
                    if (r.Multiplicity == RelationMultiplicity.Element)
                    {
                        System.Diagnostics.Debug.Assert(refClass.Oid.OidColumns.Count == r.ForeignKeyColumns.Count());
                    }
                    else
                    {
                        System.Diagnostics.Debug.Assert(c.Oid.OidColumns.Count == r.ForeignKeyColumns.Count());
                    }
#endif
                    new ForeignKeyIterator(r).Iterate(delegate(ForeignKeyColumn fkColumn, bool isLastElement)
                    {
                        if (r.Multiplicity == RelationMultiplicity.Element)
                        {
                            if (refClass.Oid.IsDependent)
                            {
                                throw new NDOException(36, String.Format("Wrong Relation '{0}.{1}'. Relations to intermediate classes are not allowed.", c.FullName, r.FieldName));
                            }
                            childCol = dt.Columns[fkColumn.Name];
                            if (childCol == null)
                            {
                                throw new InternalException(82, String.Format("SchemaGenerator: GenerateRelations: Column {0}.{1} not found", dt.TableName, fkColumn.Name));
                            }
                            string oidColumnName = ((OidColumn)refClass.Oid.OidColumns[colIndex]).Name;
                            parentCol            = foreignTable.Columns[oidColumnName];
                            if (parentCol == null)
                            {
                                throw new InternalException(85, String.Format("SchemaGenerator: GenerateRelations: Column {0}.{1} is null", foreignTable.TableName, oidColumnName));
                            }
                        }
                        else
                        {
                            if (c.Oid.IsDependent)
                            {
                                throw new NDOException(36, String.Format("Wrong Relation '{0}.{1}'. Relations to intermediate classes are not allowed.", c.FullName, r.FieldName));
                            }
                            childCol = foreignTable.Columns[fkColumn.Name];
                            if (childCol == null)
                            {
                                throw new InternalException(91, String.Format("SchemaGenerator: GenerateRelations: Column {0}.{1} not found", foreignTable.TableName, fkColumn.Name));
                            }
                            string oidColumnName = ((OidColumn)c.Oid.OidColumns[colIndex]).Name;
                            parentCol            = dt.Columns[oidColumnName];
                            if (parentCol == null)
                            {
                                throw new InternalException(94, String.Format("SchemaGenerator: GenerateRelations: Column {0}.{1} ist null", dt.TableName, oidColumnName));
                            }
                        }
                        if (null == dsSchema.Relations[relName])
                        {
                            bool parentFound = false;
                            bool childFound  = false;
                            foreach (DataRelation existingDr in dsSchema.Relations)
                            {
                                foreach (DataColumn pcol in existingDr.ParentColumns)
                                {
                                    if (pcol == parentCol)
                                    {
                                        parentFound = true;
                                        break;
                                    }
                                }
                                foreach (DataColumn ccol in existingDr.ChildColumns)
                                {
                                    if (ccol == childCol)
                                    {
                                        childFound = true;
                                        break;
                                    }
                                }
                                if (parentFound && childFound)
                                {
                                    Trace.WriteLine("Relation with this columns exists. New Relation: " + relName + ". Existing Relation: " + existingDr.RelationName);
                                }
                            }
                            if (!parentFound || !childFound)
                            {
                                DataRelation dr = new DataRelation(relName, parentCol, childCol, true);
                                dsSchema.Relations.Add(dr);
                                ForeignKeyConstraint fkc = dr.ChildKeyConstraint;
                                fkc.UpdateRule           = Rule.Cascade;
                                fkc.DeleteRule           = Rule.None;
                                fkc.AcceptRejectRule     = AcceptRejectRule.None;
                            }
                        }
                        colIndex++;
                    }); // End delegate
                }
                catch (Exception ex)
                {
                    throw new InvalidConstraintException("Can't build relation '" + r.ToString() + "'. " + ex.Message, ex);
                }
            }
        }
コード例 #7
0
ファイル: SchemaGenerator.cs プロジェクト: mirkomaty/NDO
        public void GenerateTables()
        {
            string pureName = c.FullName;
            //MM 1 DataTable anlegen
            DataTable dt = dsSchema.Tables[c.TableName];

            if (null == dt)
            {
                dt = new DataTable(c.TableName);
                dsSchema.Tables.Add(dt);
            }

            if (!c.Oid.IsDependent)              // Columns will be built as foreign key columns of the relations
            {
                List <DataColumn> primaryKeyColumns = new List <DataColumn>();
                new OidColumnIterator(c).Iterate(delegate(OidColumn oidColumnMapping, bool isLastElement)
                {
                    //MM 3 Oid-Spalte anlegen
                    DataColumn oidDataColumn = SearchAndAddColumn(dt, oidColumnMapping.Name, oidColumnMapping.SystemType);
                    // The name might have been changed while generating the column, so the mapping has to change
                    oidColumnMapping.Name = oidDataColumn.ColumnName;

                    oidDataColumn.AllowDBNull = false;
                    oidDataColumn.Unique      = c.Oid.OidColumns.Count == 1;

                    //Wenn es einen Hint gibt [NDOOidType(typeof(int))], dann muss
                    // AutoIncrement auf false stehen.
                    //bool autoIncrement = c.SystemType.GetCustomAttributes(typeof(NDOOidTypeAttribute), true).Length == 0;

                    //MM 3.1 Auto-Inkrement-Parameter setzen
                    if (oidColumnMapping.AutoIncremented && oidDataColumn.DataType == typeof(int))
                    {
                        oidDataColumn.AutoIncrement     = true;
                        oidDataColumn.AutoIncrementSeed = -(oidColumnMapping.AutoIncrementStart);
                        oidDataColumn.AutoIncrementStep = -(oidColumnMapping.AutoIncrementStep);
                    }

                    //MM 3.2 Primary Key der Tabelle auf die Oid-Spalte setzen
                    primaryKeyColumns.Add(oidDataColumn);
                }); // End Delegate
                DataColumn[] oidColums = new DataColumn[primaryKeyColumns.Count];
                primaryKeyColumns.CopyTo(oidColums);
                dt.PrimaryKey = oidColums;
            }
            string fname;

            //MM 3.3 Falls eine TimeStamp-Spalte existiert, diese anlegen
            //Timestamps sind immer vom Typ Guid
            if (c.TimeStampColumn != null)
            {
                SearchAndAddColumn(dt, c.TimeStampColumn, typeof(Guid));
            }

            //MM 3.4 If a TypeNameColumn exists in the mapping, create it
            if (c.TypeNameColumn != null)
            {
                DataColumn tnc = SearchAndAddColumn(dt, c.TypeNameColumn.Name, Type.GetType(c.TypeNameColumn.NetType));
                tnc.AllowDBNull = false;
            }


            //MM 4 Felder anlegen
            foreach (Field f in c.Fields)
            {
                fname = (string)f.Name;
//				string[] strarr = fname.Split('.');
//				string currentFieldName = string.Empty;
//				Type parentType = c.SystemType;
//				FieldInfo fi = null;
//				for(int i = 0; i < strarr.Length; i++)
//				{
//					currentFieldName += strarr[i];
//					fi = parentType.GetField(strarr[i], BindingFlags.NonPublic | BindingFlags.Instance);
//					if (null == fi)
//					{
//						throw new NDOExceptggion("Class " + pureName + " doesn't hava a field '" + currentFieldName + "'. Check your mapping file.");
//						break;
//					}
//					if (i < strarr.Length - 1)
//					{
//						currentFieldName += '.';
//						parentType = fi.FieldType;
//					}
//				}
//				if (fi == null)
//					throw new Exception("Field Type not found");
                //continue;
                if (!this.persistentFields.ContainsKey(fname))
                {
                    continue;                           // protected inherited field
                }
                object memberInfo = this.persistentFields[fname];

                Type t;
                if (memberInfo is FieldInfo)
                {
                    t = ((FieldInfo)memberInfo).FieldType;
                }
                else
                {
                    t = ((PropertyInfo)memberInfo).PropertyType;
                }
                // Don't use f.ColumnType here. This is used
                // for the definition of special Sql data types.
                SearchAndAddColumn(dt, f.Column.Name, t, f.Column.Size);
            }


            //MM 4 Relations anlegen
            //MM 4.1 Relations anlegen - 1:1 und solche mit Mapping Table

            foreach (Relation r in c.Relations)
            {
                string rname = r.FieldName;

                NDO.Mapping.Class refClass = this.mappings.FindClass(r.ReferencedType);
                if (null == refClass)
                {
                    throw new InternalException(219, "SchemaGenerator.");
//					messages.WriteLine("Fehler im Schemagenerator: Kann Mapping-Information für Klasse " + ri.RefType + " nicht finden");
//					messages.WriteInsertedLine("Referenzierte Klasse muss persistent sein");
//					continue;
                }

                //MM 5 ggf. MappingTable anlegen
                // Gibt's ne MappingTable in ri?
                if (null != r.MappingTable)
                {
                    GenerateMappingTable(c, refClass, r, dt);
                }
                else                 // Keine Mapping-Tabelle
                {
                    //MM 5.1 wenns keine Mapping Table gibt: Foreign Key Spalten anlegen
                    //MM 5.1.1 1:1 - FK ist in eigener Tabelle
                    //MM 5.1.2 nicht 1:1 - FK ist in fremder Tabelle
                    //MM 5.1.2 dies soll die Gegenklasse erledigen

                    if (r.Multiplicity == RelationMultiplicity.Element)
                    {
                        new ForeignKeyIterator(r).Iterate(delegate(ForeignKeyColumn fkColumn, bool isLastElement)
                        {
                            //    Wenn noch nicht vorhanden:
                            //    Lege Spalte r.ForeignKeyColumnName in dt an
                            SearchAndAddColumn(dt, fkColumn.Name, fkColumn.SystemType);
                        }); // End Delegate
                        if (r.ForeignKeyTypeColumnName != null)
                        {
                            SearchAndAddColumn(dt, r.ForeignKeyTypeColumnName, typeof(int));
                        }
                    }
                }
            }

            //MM 5.1.2 nicht 1:1 - FK ist in fremder Tabelle
            //wir legen nicht die Fremdschlüssel in der fremden Tabelle an, sondern
            //die Schlüssel fremder Relationen in der eigenen Tabelle
            foreach (NDO.Mapping.Class cl in mappings.Classes)
            {
                foreach (Relation r in cl.Relations)
                {
                    if (r.MappingTable == null && r.ReferencedType.IsAssignableFrom(c.SystemType))
                    {
                        if (r.Multiplicity == RelationMultiplicity.List)
                        {
                            new ForeignKeyIterator(r).Iterate(delegate(ForeignKeyColumn fkColumn, bool isLastElement)
                            {
                                // 1:n-Relation auf unsere Klasse - Schlüssel muss bei uns rein
                                SearchAndAddColumn(dt, fkColumn.Name, fkColumn.SystemType);
                            });

                            // Wir müssen auf die TypeColumn Rücksicht nehmen.
                            // Das ist die Umkehrung einer 1:n-Beziehung, wir befinden
                            // uns auf der 1-Seite. Ist die 1-Seite polymorph, entspricht
                            // das einer polymorphen Element-Beziehung.
                            if (r.ForeignKeyTypeColumnName != null)
                            {
                                SearchAndAddColumn(dt, r.ForeignKeyTypeColumnName, typeof(int));
                            }
                        }
                    }
                }
            }
        }
コード例 #8
0
ファイル: ChangeLog.cs プロジェクト: mirkomaty/NDO
        /// <summary>
        /// Initializes the ChangeLog from an object
        /// </summary>
        /// <param name="o"></param>
        public void Initialize(object o)
        {
            IPersistenceCapable pc = pm.CheckPc(o);

            // No changes
            if (pc.NDOObjectState == NDOObjectState.Hollow)
            {
                return;
            }

            if (pc.NDOObjectState != NDOObjectState.Persistent)
            {
                DataRow row = pm.GetClonedDataRow(o);

                NDO.Mapping.Class cls = pm.NDOMapping.FindClass(o.GetType());

                foreach (Field field in cls.Fields)
                {
                    string colName     = field.Column.Name;
                    object currentVal  = row[colName, DataRowVersion.Current];
                    object originalVal = row[colName, DataRowVersion.Original];

                    if (!currentVal.Equals(originalVal))
                    {
                        original.Add(field.Name, originalVal);
                        current.Add(field.Name, currentVal);
                    }
                }
            }

            var objRelationChanges = pm.RelationChanges.Where(ce => ce.Parent.NDOObjectId == pc.NDOObjectId).GroupBy(ce => ce.RelationName).ToList();

            if (objRelationChanges.Count > 0)
            {
                var relStates = pm.CollectRelationStates(pc);
                foreach (var group in objRelationChanges)
                {
                    string fieldName  = group.Key;
                    object fieldValue = (from rs in relStates where rs.Key.FieldName == fieldName select rs.Value).SingleOrDefault();
                    var    relCurrent = new ObjectIdList();
                    if (fieldValue is IList l)
                    {
                        foreach (IPersistenceCapable item in l)
                        {
                            relCurrent.Add(item.NDOObjectId);
                        }
                    }
                    else
                    {
                        if (fieldValue != null)
                        {
                            relCurrent.Add(((IPersistenceCapable)fieldValue).NDOObjectId);
                        }
                    }

                    // Make a copy
                    var relOriginal = relCurrent.Clone();

                    // In order to get the original array, we remove added objects
                    // and add removed objects
                    foreach (var changeEntry in group)
                    {
                        if (changeEntry.IsAdded)
                        {
                            var oid = changeEntry.Child.NDOObjectId;
                            if (relOriginal.Contains(oid))
                            {
                                relOriginal.Remove(oid);
                            }
                        }
                        else
                        {
                            relOriginal.Add(changeEntry.Child.NDOObjectId);
                        }
                    }
                    original.Add(fieldName, relOriginal);
                    current.Add(fieldName, relCurrent);
                }
            }
        }
コード例 #9
0
ファイル: MappingGenerator.cs プロジェクト: mirkomaty/NDO
        void CheckRelation(Test test, RelInfo ri)
        {
            if (!ri.HasTable)
            {
                return;
            }
            NDO.Mapping.Class clMapping = mapping.FindClass("RelationTestClasses." + test.OwnClass.Name);

            if (clMapping == null)
            {
                return;
            }
            NDO.Mapping.Relation rel = (NDO.Mapping.Relation)clMapping.Relations.FirstOrDefault();
            Debug.Assert(rel != null, "Relation mapping not found");
            if (rel == null)
            {
                throw new Exception("Cant find relation 0 of" + test.OwnClass.Name);
            }

            NDO.Mapping.Class    derivedMapping;
            NDO.Mapping.Relation derivedRel = null;

            if (ri.OwnPoly)
            {
                derivedMapping = mapping.FindClass("RelationTestClasses." + test.OwnDerivedClass.Name);
                if (derivedMapping == null)
                {
                    return;
                }
                derivedRel = (NDO.Mapping.Relation)derivedMapping.Relations.FirstOrDefault();
                if (rel == null)
                {
                    throw new Exception("Cant find relation 0 of" + test.OwnDerivedClass.Name);
                }
            }

            if (rel.MappingTable == null || ri.OwnPoly && derivedRel.MappingTable == null)
            {
                string tableName = null;
                if (test.OwnClass.Name.CompareTo(test.OtherClass.Name) < 0)
                {
                    tableName = "rel" + test.OwnClass.Name + test.OtherClass.Name;
                }
                else
                {
                    tableName = "rel" + test.OtherClass.Name + test.OwnClass.Name;
                }
                ForeignKeyColumn fkColumn = rel.NewForeignKeyColumn();
                fkColumn.Name = "ID" + test.OwnClass.Name;
                if (ri.OwnPoly)
                {
                    rel.ForeignKeyTypeColumnName = "TC" + test.OwnClass.Name;
                }
                else
                {
                    rel.ForeignKeyTypeColumnName = null;
                }
                rel.MappingTable           = new NDO.Mapping.MappingTable(rel);
                rel.MappingTable.TableName = tableName;
                fkColumn      = rel.MappingTable.NewForeignKeyColumn();
                fkColumn.Name = "ID" + test.OtherClass.Name;
                if (ri.OtherPoly)
                {
                    rel.MappingTable.ChildForeignKeyTypeColumnName = "TC" + test.OtherClass.Name;
                }
                else
                {
                    rel.MappingTable.ChildForeignKeyTypeColumnName = null;
                }
                rel.MappingTable.ConnectionId = clMapping.ConnectionId;

                if (ri.OwnPoly)
                {
                    ForeignKeyColumn dfkColumn = (ForeignKeyColumn)derivedRel.ForeignKeyColumns.FirstOrDefault();
                    dfkColumn.Name = ((ForeignKeyColumn)rel.ForeignKeyColumns.FirstOrDefault()).Name;
                    derivedRel.ForeignKeyTypeColumnName = rel.ForeignKeyTypeColumnName;
                    derivedRel.MappingTable             = rel.MappingTable;
                }
            }
        }
コード例 #10
0
        void IFieldInitializer.InitFields()
        {
            if (this.isInitialized)
            {
                return; // Avoid redundant calls, since InitFields is called in a recursive algorithm
            }
            this.isInitialized = true;

            Type     oidTypeHint = this.OidTypeHint;
            FieldMap fieldMap    = new FieldMap(Parent);
            Dictionary <string, MemberInfo> myPersistentFields = fieldMap.PersistentFields;
            List <string> relationsReady = new List <string>();

            bool isDependent = ((OidColumn)oidColumns[0]).RelationName != null;

            foreach (OidColumn column in this.oidColumns)
            {
                if (isDependent && column.RelationName == null ||
                    !isDependent && column.RelationName != null)
                {
                    throw new NDOException(113, "Wrong Oid mapping for type " + Parent.FullName + ". You can't mix OidColumns with and without a RelationName.");
                }
            }

            foreach (OidColumn column in this.oidColumns)
            {
                if (column.FieldName != null)
                {
                    if (!myPersistentFields.ContainsKey(column.FieldName))
                    {
                        throw new NDOException(20, "Can't find field " + Parent.FullName + "." + column.FieldName + '.');
                    }
                    FieldInfo fi = (FieldInfo)myPersistentFields[column.FieldName];
                    column.SystemType = fi.FieldType;
                    Field fieldMapping = Parent.FindField(fi.Name);
                    if (fieldMapping == null)
                    {
                        throw new NDOException(7, "Can't find mapping information for field " + Parent.FullName + "." + fi.Name);
                    }

                    // This information will be deleted by the enhancer after generating the schema
                    // to avoid redundant information in the mapping file.
                    column.Name = fieldMapping.Column.Name;
                }
                else if (column.RelationName != null)
                {
                    // Find and check the relation
                    Relation r = Parent.FindRelation(column.RelationName);
                    if (r == null || r.Multiplicity != RelationMultiplicity.Element || r.Composition)
                    {
                        throw new NDOException(109, "Wrong relation name " + column.RelationName + " in OidColumn definition of type " + Parent.FullName + '.' + " The RelationName must denote an existing assoziation with RelationMultiplicity.Element.");
                    }

                    bool found = false;
                    foreach (string s in relationsReady)
                    {
                        if (column.RelationName == s)
                        {
                            found = true;
                            break;
                        }
                    }
                    if (!found)
                    {
                        relationsReady.Add(column.RelationName);
                        // find all oid columns with the same RelationName
                        List <OidColumn> allOidColumns = this.oidColumns.Where(oidc => oidc.RelationName == column.RelationName).ToList();

                        // find all FkColumns of the relation
                        List <ForeignKeyColumn> fkColumns = r.ForeignKeyColumns.ToList();

                        // Both lists must have the same count
                        if (allOidColumns.Count != fkColumns.Count)
                        {
                            throw new NDOException(110, "Count of Oid columns with relation name " + column.RelationName + " is different from count of foreign key columns of the named relation. Expected: " + fkColumns.Count + ". Count of OidColumns was: " + allOidColumns.Count + '.' + " Type = " + Parent.FullName + '.');
                        }

                        // Now let's determine the oid types of the columns
                        Class relClass = Parent.Parent.FindClass(r.ReferencedTypeName);

                        // Resolve the Oid types of the related type. Endless recursion is not possible because of the test at the beginning of this method.
                        if (allOidColumns.Count != relClass.Oid.OidColumns.Count())
                        {
                            throw new NDOException(110, "Count of Oid columns with relation name " + column.RelationName + " is different from count of oid columns of the related type. Expected: " + fkColumns.Count + ". Count of OidColumns was: " + allOidColumns.Count + '.' + " Type = " + Parent.FullName + '.');
                        }
                        ((IFieldInitializer)relClass).InitFields();  // Must initialize the system type and oid of the related class first.
                        int i = 0;
                        foreach (OidColumn relOidColumn in relClass.Oid.OidColumns)
                        {
                            // The column has the same type as the oid column of the related type
                            ((OidColumn)allOidColumns[i]).SystemType = relOidColumn.SystemType;
                            // The column has the same name as the foreign key column of the relation defined
                            // by RelationName.
                            // The enhancer will remove the name assigned here after generating the schema.
                            ((OidColumn)allOidColumns[i]).Name = ((Column)fkColumns[i]).Name;
                            i++;
                        }
                    }
                }
                else if (column.NetType != null)
                {
                    column.SystemType = Type.GetType(column.NetType);
                    if (column.SystemType == null)
                    {
                        throw new NDOException(11, "Type.GetType for the type name " + column.NetType + " failed; check your mapping File.");
                    }
                }
                else if (oidTypeHint != null && this.oidColumns.Count == 1)
                {
                    column.SystemType = oidTypeHint;
                }
                else  // Default case if nothing is defined in the mapping or in NDOOidType
                {
                    column.SystemType = typeof(Int32);
                    if (this.oidColumns.Count == 1)
                    {
                        column.AutoIncremented = true;
                    }
                }
            }

            if (!((IEnhancerSupport)Parent.Parent).IsEnhancing)
            {
                int autoIncCount = 0;
                foreach (OidColumn column in this.oidColumns)
                {
                    // The size is only set for internal use by NDO.
                    // Don't save this information in the mapping file.
                    if (column.Size == 0)
                    {
                        column.Size = Parent.Parent.GetProvider(Parent).GetDefaultLength(column.SystemType);
                    }
                    if (column.AutoIncremented)
                    {
                        autoIncCount++;
                    }
                }
                if (autoIncCount > 1)
                {
                    throw new NDOException(112, "Type " + Parent.FullName + " has more than one autoincremented column. This is not supported by NDO. Check your mapping file or the OidColumn attributes in the source code.");
                }
            }
        }
コード例 #11
0
 void CheckFields(TableNode tn, NDO.Mapping.Class cl)
 {
 }
コード例 #12
0
 void MapClass(TableNode tn, NDO.Mapping.Class cl)
 {
     tn.MapIntermediateClass(null, EventArgs.Empty);
 }
コード例 #13
0
ファイル: SchemaGenerator.cs プロジェクト: mirkomaty/NDO
        public void GenerateRelations()
        {
            DataTable dt = dsSchema.Tables[c.TableName];

            if (null == dt)
            {
                throw new InternalException(38, String.Format("GenerateRelations: DataTable {0} not found.", c.TableName));
            }

            ClassNode classNode = (ClassNode)allPersistentClasses[c.FullName];

            if (classNode == null)
            {
                throw new InternalException(42, "SchemaGenerator: GenerateRelations");
            }

//			ReferenceArrayList references = (ReferenceArrayList) allReferences[c.FullName];
//			if (references == null)
//				throw new NDOException(string.Format("Kann Relationsinformationen für die Klasse {0} nicht finden. Rekompilieren Sie ggf. das Assembly neu", c.FullName));
//
            foreach (Relation r in c.Relations)
            {
                string rname = r.FieldName;
                if (null == r)
                {
                    messages.WriteLine("Keine Mapping-Informationen für Relation " + c.FullName + "." + rname + ". Lassen Sie sich die Information generieren oder tragen Sie sie per Hand ein.");
                    continue;
                }

                if (r.MappingTable != null)
                {
                    continue;
                }

                NDO.Mapping.Class refClass = this.mappings.FindClass(r.ReferencedTypeName);
                if (null == refClass)
                {
                    throw new InternalException(64, String.Format("Reference Class {0} nicht gefunden", r.ReferencedTypeName));
                }

                ClassNode refClassNode = (ClassNode)allPersistentClasses[refClass.FullName];

                // Kann keine Relation zu einer abstrakten Klasse herstellen,
                // da diese keine Tabelle hat
                if (refClassNode.IsAbstract)
                {
                    continue;
                }

                //MM 5.2 Relationen anlegen
                // Zwei gegenläufige 1:1-Beziehungen benötigen zwei Relationen
                DataColumn parentCol;
                DataColumn childCol;
                DataTable  foreignTable = dsSchema.Tables[refClass.TableName];
                if (foreignTable == null)
                {
                    throw new InternalException(77, String.Format("SchemaGenerator: GenerateRelations: foreign Table {0} for class {1} not found.", refClass.TableName, refClass.FullName));
                }

                string relName;
                if (r.Multiplicity == RelationMultiplicity.Element && GegenRelationIs1To1(c.FullName, refClassNode, r))
                {
                    relName = GetLastElement(dt.TableName) + GetLastElement(refClass.TableName) + r.RelationName;
                }
                else
                {
                    if (refClass.TableName.CompareTo(dt.TableName) < 0)
                    {
                        relName = GetLastElement(refClass.TableName) + GetLastElement(dt.TableName) + r.RelationName;
                    }
                    else
                    {
                        relName = GetLastElement(dt.TableName) + GetLastElement(refClass.TableName) + r.RelationName;
                    }
                }
                int i = 0;
                new ForeignKeyIterator(r).Iterate(delegate(ForeignKeyColumn fkColumn, bool isLastElement)
                {
                    if (r.Multiplicity == RelationMultiplicity.Element)
                    {
                        childCol = dt.Columns[fkColumn.Name];
                        if (childCol == null)
                        {
                            throw new Exception(String.Format("Internal Error: GenerateRelations: Column {0}.{1} not found", dt.TableName, fkColumn.Name));
                        }
                        string oidColumnName = ((OidColumn)refClass.Oid.OidColumns[i]).Name;
                        parentCol            = foreignTable.Columns[oidColumnName];
                        if (parentCol == null)
                        {
                            throw new Exception(String.Format("Internal Error: GenerateRelations: Column {0}.{1} is null", foreignTable.TableName, oidColumnName));
                        }
                    }
                    else
                    {
                        childCol = foreignTable.Columns[fkColumn.Name];
                        if (childCol == null)
                        {
                            throw new Exception(String.Format("Internal Error: GenerateRelations: Column {0}.{1} not found", foreignTable.TableName, fkColumn.Name));
                        }
                        string oidColumnName = ((OidColumn)c.Oid.OidColumns[i]).Name;
                        parentCol            = dt.Columns[oidColumnName];
                        if (parentCol == null)
                        {
                            throw new Exception(String.Format("Internal Error: GenerateRelations: Column {0}.{1} is null", dt.TableName, oidColumnName));
                        }
                    }
                    if (null == dsSchema.Relations[relName])
                    {
                        try
                        {
                            DataRelation dr = new DataRelation(relName, parentCol, childCol, true);
                            dsSchema.Relations.Add(dr);
                            ForeignKeyConstraint fkc = dr.ChildKeyConstraint;
                            fkc.UpdateRule           = Rule.Cascade;
                            fkc.DeleteRule           = Rule.None;
                            fkc.AcceptRejectRule     = AcceptRejectRule.None;
                        }
                        catch (Exception ex)
                        {
                            if (verboseMode)
                            {
                                messages.ShowError("Error while constructing relation " + relName + ": " + ex.ToString());
                            }
                            else
                            {
                                messages.ShowError("Error while constructing relation " + relName + ": " + ex.Message);
                            }
                        }
                    }
                    i++;
                });
            }

#if !NDO20
#if BETA
            if (!NDOKey.CheckKey(new Guid("889b6a58-1d97-be54-d874-75a12a93f56e"),
                                 new LicenceKey().TheKey))
            {
                throw new WrongLicenceException2();
            }
#else
#if TRIAL
            if (!NDOKey.CheckKey(new Guid("7f63d54d-d500-228e-311d-b19bb99d9bd4"),
                                 new LicenceKey().TheKey))
            {
                throw new WrongLicenceException2();
            }
#else
#if ENT
            if (!NDOKey.CheckKey(new Guid("9d092588-f787-cbed-fe06-2dcd86720337"),
                                 new LicenceKey().TheKey))
            {
                throw new WrongLicenceException2();
            }
#else
#if PRO
            if (!NDOKey.CheckKey(new Guid("ed25a316-3365-1e4e-5144-f3a1766fe98d"),
                                 new LicenceKey().TheKey))
            {
                throw new WrongLicenceException2();
            }
#else
#if STD
            if (!NDOKey.CheckKey(new Guid("ec3be943-c358-b83a-e310-b8436322e322"),
                                 new LicenceKey().TheKey))
            {
                throw new WrongLicenceException2();
            }
#endif
#endif
#endif
#endif
#endif
#else  // NDO20
#if BETA
            if (!NDOKey.CheckKey(new Guid("2f29c228-6967-4941-02dd-369783fabdde"),
                                 new LicenceKey().TheKey))
            {
                throw new WrongLicenceException2();
            }
#else
#if TRIAL
            if (!NDOKey.CheckKey(new Guid("629dab4d-a032-a30e-54ea-1a53e0111cb9"),
                                 new LicenceKey().TheKey))
            {
                throw new WrongLicenceException2();
            }
#else
#if ENT
            if (!NDOKey.CheckKey(new Guid("9540866a-861c-3f19-ae8c-7f9785f62ce5"),
                                 new LicenceKey().TheKey))
            {
                throw new WrongLicenceException2();
            }
#else
#if PRO
            if (!NDOKey.CheckKey(new Guid("35473777-9fc3-f78f-83c6-475f23758b46"),
                                 new LicenceKey().TheKey))
            {
                throw new WrongLicenceException2();
            }
#else
#if STD
            if (!NDOKey.CheckKey(new Guid("36bf154d-4085-9f38-d2a9-1fea6a6f9df8"),
                                 new LicenceKey().TheKey))
            {
                throw new WrongLicenceException2();
            }
#endif
#endif
#endif
#endif
#endif
#endif // NDO20
        }
コード例 #14
0
ファイル: SchemaGenerator.cs プロジェクト: mirkomaty/NDO
        public void GenerateTables()
        {
            string pureName = c.FullName;
            //MM 1 DataTable anlegen
            DataTable dt = dsSchema.Tables[c.TableName];

            if (null == dt)
            {
                dt = new DataTable(c.TableName);
                dsSchema.Tables.Add(dt);
            }

            //MM 2 Name des Oid-Fields bestimmen
            if (!c.Oid.IsDependent)
            {
                ArrayList primaryKeyColumns = new ArrayList();
                new OidColumnIterator(c).Iterate(delegate(OidColumn oidColumn, bool isLastElement)
                {
                    //MM 3 Oid-Spalte anlegen
                    DataColumn oidDataColumn = searchAndAddColumn(dt, oidColumn.Name, null, oidColumn.SystemType);
                    // Der Name kann sich beim Anlegen geändert haben
                    oidColumn.Name = oidDataColumn.ColumnName;

                    oidDataColumn.AllowDBNull = false;
                    oidDataColumn.Unique      = true;

                    //Wenn es einen Hint gibt [NDOOidType(typeof(int))], dann muss
                    // AutoIncrement auf false stehen.
                    //ClassNode classNode = (ClassNode)allPersistentClasses[c.FullName];
                    //if (classNode == null)
                    //    throw new InternalException(170, "SchemaGenerator");

                    //bool autoIncrement = true;
                    //autoIncrement = classNode.OidType == null;


                    //MM 3.1 Auto-Increment-Parameter setzen
                    if (oidColumn.AutoIncremented)
                    {
                        oidDataColumn.AutoIncrement     = true;
                        oidDataColumn.AutoIncrementSeed = -1;
                        oidDataColumn.AutoIncrementStep = -1;
                    }

                    //MM 3.2 Primary Key der Tabelle auf die Oid-Spalte setzen
                    primaryKeyColumns.Add(oidDataColumn);
                }); // End Delegate
                DataColumn[] oidColums = new DataColumn[primaryKeyColumns.Count];
                primaryKeyColumns.CopyTo(oidColums);
                dt.PrimaryKey = oidColums;
            }
            string fname;

            //MM 3.3 Falls eine TimeStamp-Spalte existiert, diese anlegen
            //Timestamps sind immer vom Typ byte[]
            if (c.TimeStampColumn != null)
            {
                searchAndAddColumn(dt, c.TimeStampColumn, null, typeof(Guid));
            }

            //MM 3.4 Falls eine TypeNameColumn existiert, eine anlegen
            if (c.TypeNameColumn != null)
            {
                DataColumn tnc = searchAndAddColumn(dt, c.TypeNameColumn.Name, null, Type.GetType(c.TypeNameColumn.NetType));
                tnc.AllowDBNull = false;
            }

            //MM 4 Felder anlegen
            IList sortedFields = (IList)allSortedFields[pureName];

            if (sortedFields != null)             // other assembly
            {
                foreach (DictionaryEntry de in sortedFields)
                {
                    fname = (string)de.Key;
                    Patcher.ILField fi = (Patcher.ILField)de.Value;

                    NDO.Mapping.Field f = c.FindField(fname);
                    if (null == f)
                    {
                        messages.WriteLine("Keine Mapping-Informationen für Feld " + pureName + "." + fname + ". Lassen Sie sich die Information generieren oder tragen Sie sie per Hand ein.");
                        continue;
                    }
                    // Hier wird nicht der f.ColumnType verwendet. Dieser ist für
                    // spezielle Sql-Datentypen gedacht
                    searchAndAddColumn(dt, f.Column.Name, fi.IsEnum ? "System.Int32" : fi.CsType, typeof(string));
                }
            }

            //MM 4 Relations anlegen
            //MM 4.1 Relations anlegen - 1:1 und solche mit Mapping Table
//			ReferenceArrayList references = (ReferenceArrayList) allReferences[pureName];
//			if (references == null)
//				throw new NDOException(string.Format("Kann Relationsinformationen für die Klasse {0} nicht finden. Rekompilieren Sie ggf. das Assembly neu", pureName));

            foreach (Relation r in c.Relations)
            {
                string rname = r.FieldName;
//				NDO.Mapping.Relation r = c.FindRelation(rname);
                if (null == r)
                {
                    messages.WriteLine("Keine Mapping-Informationen für Relation " + pureName + "." + rname + ". Lassen Sie sich die Information generieren oder tragen Sie sie per Hand ein.");
                    continue;
                }

                NDO.Mapping.Class refClass = this.mappings.FindClass(r.ReferencedTypeName);
                if (null == refClass)
                {
                    throw new Exception("Can't find class mapping for type " + r.ReferencedTypeName + ". Check your mapping file or merge the mapping information from your base assemblies.");
                }

                //MM 5 ggf. MappingTable anlegen
                // Gibt's ne MappingTable in ri?
                if (null != r.MappingTable)
                {
                    GenerateMappingTable(c, refClass, r, dt);
                }
                else                 // Keine Mapping-Tabelle
                {
                    //MM 5.1 wenns keine Mapping Table gibt: Foreign Key Spalten anlegen
                    //MM 5.1.1 1:1 - FK ist in eigener Tabelle
                    //MM 5.1.2 nicht 1:1 - FK ist in fremder Tabelle
                    //MM 5.1.2 dies soll die Gegenklasse erledigen

                    if (r.Multiplicity == RelationMultiplicity.Element)
                    {
                        //    Wenn noch nicht vorhanden:
                        //    Lege Spalte r.ForeignKeyColumnName in dt an
                        new ForeignKeyIterator(r).Iterate(delegate(ForeignKeyColumn fkColumn, bool isLastElement)
                        {
                            searchAndAddColumn(dt, fkColumn.Name, null, fkColumn.SystemType);
                        });

                        if (r.ForeignKeyTypeColumnName != null)
                        {
                            searchAndAddColumn(dt, r.ForeignKeyTypeColumnName, null, typeof(int));
                        }
                    }
                }
            }

            //MM 5.1.2 nicht 1:1 - FK ist in fremder Tabelle
            //wir legen nicht die Fremdschlüssel in der fremden Tabelle an, sondern
            //die Schlüssel fremder Relationen in der eigenen Tabelle
            foreach (NDO.Mapping.Class cl in mappings.Classes)
            {
                foreach (Relation r in cl.Relations)
                {
                    if (r.MappingTable == null && ReferencedNameIsAssignable(r.ReferencedTypeName))
                    {
                        if (r.Multiplicity == RelationMultiplicity.List)
                        {
                            new ForeignKeyIterator(r).Iterate(delegate(ForeignKeyColumn fkColumn, bool isLastElement)
                            {
                                // 1:n-Relation auf unsere Klasse - Schlüssel muss bei uns rein
                                searchAndAddColumn(dt, fkColumn.Name, null, fkColumn.SystemType);
                            });

                            // Wir müssen auf die TypeColumn Rücksicht nehmen.
                            // Das ist die Umkehrung einer 1:n-Beziehung, wir befinden
                            // uns auf der 1-Seite. Ist die 1-Seite polymorph, entspricht
                            // das einer polymorphen Element-Beziehung.
                            if (r.ForeignKeyTypeColumnName != null)
                            {
                                searchAndAddColumn(dt, r.ForeignKeyTypeColumnName, null, typeof(int));
                            }
                        }
                    }
                }
            }
        }
コード例 #15
0
 /// <inheritdoc/>
 protected override void WriteLostForeignKeysToRow(NDO.Mapping.Class cl, IPersistenceCapable pc, DataRow row)
 {
     // We simply don't write the keys.
 }
コード例 #16
0
 void CheckRelations(TableNode tn, NDO.Mapping.Class cl)
 {
 }
コード例 #17
0
 /// <summary>
 /// Calls to this methods are ignored.
 /// </summary>
 /// <param name="cl"></param>
 /// <param name="row"></param>
 public override void ToRow(NDO.Mapping.Class cl, DataRow row)
 {
     // Nothing to do
 }
コード例 #18
0
 /// <summary>
 /// Constructs a new Oid
 /// </summary>
 public ClassOid(Class parent)
     : base(parent)
 {
 }