Exemple #1
0
		private static void WriteChildElements(DslModeling::SerializationContext serializationContext, ModelClass element, global::System.Xml.XmlWriter writer)
		{
			// ManyToOneRelation
			global::System.Collections.ObjectModel.ReadOnlyCollection<ManyToOneRelation> allManyToOneRelationInstances = ManyToOneRelation.GetLinksToTargets(element);
			if (!serializationContext.Result.Failed && allManyToOneRelationInstances.Count > 0)
			{
				writer.WriteStartElement("targets");
				foreach (ManyToOneRelation eachManyToOneRelationInstance in allManyToOneRelationInstances)
				{
					if (serializationContext.Result.Failed)
						break;
	
					DslModeling::DomainClassXmlSerializer relSerializer = serializationContext.Directory.GetSerializer(eachManyToOneRelationInstance.GetDomainClass().Id);
					global::System.Diagnostics.Debug.Assert(relSerializer != null, "Cannot find serializer for " + eachManyToOneRelationInstance.GetDomainClass().Name + "!");
					relSerializer.Write(serializationContext, eachManyToOneRelationInstance, writer);
				}
				writer.WriteEndElement();
			}
	
			// ClassHasProperty
			global::System.Collections.ObjectModel.ReadOnlyCollection<ClassHasProperty> allClassHasPropertyInstances = ClassHasProperty.GetLinksToProperties(element);
			if (!serializationContext.Result.Failed && allClassHasPropertyInstances.Count > 0)
			{
				writer.WriteStartElement("properties");
				global::System.Type typeofClassHasProperty = typeof(ClassHasProperty);
				foreach (ClassHasProperty eachClassHasPropertyInstance in allClassHasPropertyInstances)
				{
					if (serializationContext.Result.Failed)
						break;
	
					if (eachClassHasPropertyInstance.GetType() != typeofClassHasProperty)
					{	// Derived relationships will be serialized in full-form.
						DslModeling::DomainClassXmlSerializer derivedRelSerializer = serializationContext.Directory.GetSerializer(eachClassHasPropertyInstance.GetDomainClass().Id);
						global::System.Diagnostics.Debug.Assert(derivedRelSerializer != null, "Cannot find serializer for " + eachClassHasPropertyInstance.GetDomainClass().Name + "!");			
						derivedRelSerializer.Write(serializationContext, eachClassHasPropertyInstance, writer);
					}
					else
					{	// No need to serialize the relationship itself, just serialize the role-player directly.
						DslModeling::ModelElement targetElement = eachClassHasPropertyInstance.Property;
						DslModeling::DomainClassXmlSerializer targetSerializer = serializationContext.Directory.GetSerializer(targetElement.GetDomainClass().Id);
						global::System.Diagnostics.Debug.Assert(targetSerializer != null, "Cannot find serializer for " + targetElement.GetDomainClass().Name + "!");			
						targetSerializer.Write(serializationContext, targetElement, writer);
					}
				}
				writer.WriteEndElement();
			}
	
			// ManyToManyRelation
			global::System.Collections.ObjectModel.ReadOnlyCollection<ManyToManyRelation> allManyToManyRelationInstances = ManyToManyRelation.GetLinksToManyToManyTargets(element);
			if (!serializationContext.Result.Failed && allManyToManyRelationInstances.Count > 0)
			{
				writer.WriteStartElement("manyToManyTargets");
				foreach (ManyToManyRelation eachManyToManyRelationInstance in allManyToManyRelationInstances)
				{
					if (serializationContext.Result.Failed)
						break;
	
					DslModeling::DomainClassXmlSerializer relSerializer = serializationContext.Directory.GetSerializer(eachManyToManyRelationInstance.GetDomainClass().Id);
					global::System.Diagnostics.Debug.Assert(relSerializer != null, "Cannot find serializer for " + eachManyToManyRelationInstance.GetDomainClass().Name + "!");
					relSerializer.Write(serializationContext, eachManyToManyRelationInstance, writer);
				}
				writer.WriteEndElement();
			}
	
			// OneToOneRelation
			OneToOneRelation theOneToOneRelationInstance = OneToOneRelation.GetLinkToOneToOneTarget(element);
			if (!serializationContext.Result.Failed && theOneToOneRelationInstance != null)
			{
				writer.WriteStartElement("oneToOneTarget");
				DslModeling::DomainClassXmlSerializer relSerializer = serializationContext.Directory.GetSerializer(theOneToOneRelationInstance.GetDomainClass().Id);
				global::System.Diagnostics.Debug.Assert(relSerializer != null, "Cannot find serializer for " + theOneToOneRelationInstance.GetDomainClass().Name + "!");
				relSerializer.Write(serializationContext, theOneToOneRelationInstance, writer);
				writer.WriteEndElement();
			}
	
			// InheritanceRelation
			global::System.Collections.ObjectModel.ReadOnlyCollection<InheritanceRelation> allInheritanceRelationInstances = InheritanceRelation.GetLinksToTargetModelClasses(element);
			if (!serializationContext.Result.Failed && allInheritanceRelationInstances.Count > 0)
			{
				DslModeling::DomainRelationshipXmlSerializer relSerializer = serializationContext.Directory.GetSerializer(InheritanceRelation.DomainClassId) as DslModeling::DomainRelationshipXmlSerializer;
				global::System.Diagnostics.Debug.Assert(relSerializer != null, "Cannot find serializer for InheritanceRelation!");
	
				writer.WriteStartElement("targetModelClasses");
				global::System.Type typeofInheritanceRelation = typeof(InheritanceRelation);
				foreach (InheritanceRelation eachInheritanceRelationInstance in allInheritanceRelationInstances)
				{
					if (serializationContext.Result.Failed)
						break;
	
					if (eachInheritanceRelationInstance.GetType() != typeofInheritanceRelation)
					{	// Derived relationships will be serialized in full-form.
						DslModeling::DomainClassXmlSerializer derivedRelSerializer = serializationContext.Directory.GetSerializer(eachInheritanceRelationInstance.GetDomainClass().Id);
						global::System.Diagnostics.Debug.Assert(derivedRelSerializer != null, "Cannot find serializer for " + eachInheritanceRelationInstance.GetDomainClass().Name + "!");			
						derivedRelSerializer.Write(serializationContext, eachInheritanceRelationInstance, writer);
					}
					else
					{	// No need to serialize the relationship itself, just serialize the role-player directly.
						DslModeling::ModelElement targetElement = eachInheritanceRelationInstance.TargetModelClass;
						DslModeling::DomainClassXmlSerializer targetSerializer = serializationContext.Directory.GetSerializer(targetElement.GetDomainClass().Id);
						global::System.Diagnostics.Debug.Assert(targetSerializer != null, "Cannot find serializer for " + targetElement.GetDomainClass().Name + "!");			
						targetSerializer.WriteMoniker(serializationContext, targetElement, writer, element, relSerializer);
					}
				}
				writer.WriteEndElement();
			}
	
		}
Exemple #2
0
		private static void ReadOneToOneRelationInstance(DslModeling::SerializationContext serializationContext, ModelClass element, global::System.Xml.XmlReader reader)
		{
			if (DslModeling::DomainRoleInfo.GetElementLinks<OneToOneRelation> (element, OneToOneRelation.SourceDomainRoleId).Count > 0)
			{	// Only allow one instance, which already exists, so skip everything
				DslModeling::SerializationUtilities.Skip(reader);	// Moniker contains no child XML elements, so just skip.
				return;
			}
	
			while (!serializationContext.Result.Failed && !reader.EOF && reader.NodeType == global::System.Xml.XmlNodeType.Element)
			{
				DslModeling::DomainClassXmlSerializer newOneToOneRelationSerializer = serializationContext.Directory.GetSerializer(OneToOneRelation.DomainClassId);
				global::System.Diagnostics.Debug.Assert(newOneToOneRelationSerializer != null, "Cannot find serializer for OneToOneRelation!");
				OneToOneRelation newOneToOneRelation = newOneToOneRelationSerializer.TryCreateInstance (serializationContext, reader, element.Partition) as OneToOneRelation;
				if (newOneToOneRelation != null)
				{
					DslModeling::DomainRoleInfo.SetRolePlayer (newOneToOneRelation, OneToOneRelation.SourceDomainRoleId, element);
					DslModeling::DomainClassXmlSerializer targetSerializer = serializationContext.Directory.GetSerializer (newOneToOneRelation.GetDomainClass().Id);	
					global::System.Diagnostics.Debug.Assert (targetSerializer != null, "Cannot find serializer for " + newOneToOneRelation.GetDomainClass().Name + "!");
					targetSerializer.Read(serializationContext, newOneToOneRelation, reader);
					break;	// Only allow one instance.
				}
				else
				{	// Maybe the relationship is serialized in short-form by mistake.
					DslModeling::DomainClassXmlSerializer newModelClassMonikerOfOneToOneRelationSerializer = serializationContext.Directory.GetSerializer(ModelClass.DomainClassId);
					global::System.Diagnostics.Debug.Assert(newModelClassMonikerOfOneToOneRelationSerializer != null, "Cannot find serializer for ModelClass!");
					DslModeling::Moniker newModelClassMonikerOfOneToOneRelation = newModelClassMonikerOfOneToOneRelationSerializer.TryCreateMonikerInstance(serializationContext, reader, element, OneToOneRelation.DomainClassId, element.Partition);
					if (newModelClassMonikerOfOneToOneRelation != null)
					{
						ActiveWriterSerializationBehaviorSerializationMessages.ExpectingFullFormRelationship(serializationContext, reader, typeof(OneToOneRelation));
						new OneToOneRelation(element.Partition, new DslModeling::RoleAssignment(OneToOneRelation.SourceDomainRoleId, element), new DslModeling::RoleAssignment(OneToOneRelation.TargetDomainRoleId, newModelClassMonikerOfOneToOneRelation));
						DslModeling::SerializationUtilities.Skip(reader);	// Moniker contains no child XML elements, so just skip.
						break;	// Only allow one instance.
					}
					else
					{	// Unknown element, skip.
						DslModeling::SerializationUtilities.Skip(reader);
					}
				}
			}
		}
Exemple #3
0
		private static void ReadInheritanceRelationInstances(DslModeling::SerializationContext serializationContext, ModelClass element, global::System.Xml.XmlReader reader)
		{
			while (!serializationContext.Result.Failed && !reader.EOF && reader.NodeType == global::System.Xml.XmlNodeType.Element)
			{
				DslModeling::DomainClassXmlSerializer newModelClassMonikerOfInheritanceRelationSerializer = serializationContext.Directory.GetSerializer(ModelClass.DomainClassId);
				global::System.Diagnostics.Debug.Assert(newModelClassMonikerOfInheritanceRelationSerializer != null, "Cannot find serializer for ModelClass!");
				DslModeling::Moniker newModelClassMonikerOfInheritanceRelation = newModelClassMonikerOfInheritanceRelationSerializer.TryCreateMonikerInstance(serializationContext, reader, element, InheritanceRelation.DomainClassId, element.Partition);
				if (newModelClassMonikerOfInheritanceRelation != null)
				{
					new InheritanceRelation(element.Partition, new DslModeling::RoleAssignment(InheritanceRelation.SourceModelClassDomainRoleId, element), new DslModeling::RoleAssignment(InheritanceRelation.TargetModelClassDomainRoleId, newModelClassMonikerOfInheritanceRelation));
					DslModeling::SerializationUtilities.Skip(reader);	// Moniker contains no child XML elements, so just skip.
				}
				else
				{
					global::System.Type typeofInheritanceRelation = typeof(InheritanceRelation);
					DslModeling::DomainRelationshipXmlSerializer newInheritanceRelationSerializer = serializationContext.Directory.GetSerializer(InheritanceRelation.DomainClassId) as DslModeling::DomainRelationshipXmlSerializer;
					global::System.Diagnostics.Debug.Assert(newInheritanceRelationSerializer != null, "Cannot find serializer for InheritanceRelation!");
					InheritanceRelation newInheritanceRelation = newInheritanceRelationSerializer.TryCreateInstance (serializationContext, reader, element.Partition) as InheritanceRelation;
					if (newInheritanceRelation != null)
					{
						if (newInheritanceRelation.GetType() == typeofInheritanceRelation)
						{	// The relationship should be serialized in short-form.
							ActiveWriterSerializationBehaviorSerializationMessages.ExpectingShortFormRelationship(serializationContext, reader, typeof(InheritanceRelation));
						}
						DslModeling::DomainRoleInfo.SetRolePlayer (newInheritanceRelation, InheritanceRelation.SourceModelClassDomainRoleId, element);
						DslModeling::DomainClassXmlSerializer targetSerializer = serializationContext.Directory.GetSerializer (newInheritanceRelation.GetDomainClass().Id);	
						global::System.Diagnostics.Debug.Assert (targetSerializer != null, "Cannot find serializer for " + newInheritanceRelation.GetDomainClass().Name + "!");
						targetSerializer.Read(serializationContext, newInheritanceRelation, reader);
					}
					else
					{	// Unknown element, skip
						DslModeling::SerializationUtilities.Skip(reader);
					}
				}
			}
		}
Exemple #4
0
		/// <summary>
		/// Reads all instances of relationship ClassHasProperty.
		/// </summary>
		/// <remarks>
		/// The caller will position the reader at the open tag of the first XML element inside the relationship tag, so it can be
		/// either the first instance, or a bogus tag. This method will deserialize all instances and ignore all bogus tags. When the
		/// method returns, the reader will be positioned at the end tag of the relationship (or EOF if somehow that happens).
		/// </remarks>
		/// <param name="serializationContext">Serialization context.</param>
		/// <param name="element">In-memory ModelClass instance that will get the deserialized data.</param>
		/// <param name="reader">XmlReader to read serialized data from.</param>
		private static void ReadClassHasPropertyInstances(DslModeling::SerializationContext serializationContext, ModelClass element, global::System.Xml.XmlReader reader)
		{
			while (!serializationContext.Result.Failed && !reader.EOF && reader.NodeType == global::System.Xml.XmlNodeType.Element)
			{
				DslModeling::DomainClassXmlSerializer newModelPropertyOfClassHasPropertySerializer = serializationContext.Directory.GetSerializer(ModelProperty.DomainClassId);
				global::System.Diagnostics.Debug.Assert(newModelPropertyOfClassHasPropertySerializer != null, "Cannot find serializer for ModelProperty!");
				ModelProperty newModelPropertyOfClassHasProperty = newModelPropertyOfClassHasPropertySerializer.TryCreateInstance(serializationContext, reader, element.Partition) as ModelProperty;
				if (newModelPropertyOfClassHasProperty != null)
				{
					element.Properties.Add(newModelPropertyOfClassHasProperty);
					DslModeling::DomainClassXmlSerializer targetSerializer = serializationContext.Directory.GetSerializer (newModelPropertyOfClassHasProperty.GetDomainClass().Id);	
					global::System.Diagnostics.Debug.Assert (targetSerializer != null, "Cannot find serializer for " + newModelPropertyOfClassHasProperty.GetDomainClass().Name + "!");
					targetSerializer.Read(serializationContext, newModelPropertyOfClassHasProperty, reader);
				}
				else
				{
					global::System.Type typeofClassHasProperty = typeof(ClassHasProperty);
					DslModeling::DomainRelationshipXmlSerializer newClassHasPropertySerializer = serializationContext.Directory.GetSerializer(ClassHasProperty.DomainClassId) as DslModeling::DomainRelationshipXmlSerializer;
					global::System.Diagnostics.Debug.Assert(newClassHasPropertySerializer != null, "Cannot find serializer for ClassHasProperty!");
					ClassHasProperty newClassHasProperty = newClassHasPropertySerializer.TryCreateInstance (serializationContext, reader, element.Partition) as ClassHasProperty;
					if (newClassHasProperty != null)
					{
						if (newClassHasProperty.GetType() == typeofClassHasProperty)
						{	// The relationship should be serialized in short-form.
							ActiveWriterSerializationBehaviorSerializationMessages.ExpectingShortFormRelationship(serializationContext, reader, typeof(ClassHasProperty));
						}
						DslModeling::DomainRoleInfo.SetRolePlayer (newClassHasProperty, ClassHasProperty.ModelClassDomainRoleId, element);
						DslModeling::DomainClassXmlSerializer targetSerializer = serializationContext.Directory.GetSerializer (newClassHasProperty.GetDomainClass().Id);	
						global::System.Diagnostics.Debug.Assert (targetSerializer != null, "Cannot find serializer for " + newClassHasProperty.GetDomainClass().Name + "!");
						targetSerializer.Read(serializationContext, newClassHasProperty, reader);
					}
					else
					{	// Unknown element, skip
						DslModeling::SerializationUtilities.Skip(reader);
					}
				}
			}
		}
Exemple #5
0
		/// <summary>
		/// This method deserializes all child model elements.
		/// </summary>
		/// <remarks>
		/// The caller will position the reader at the open tag of the first child XML element to deserialized.
		/// This method will read as many child elements as it can. It returns under three circumstances:
		/// 1) When an unknown child XML element is encountered. In this case, this method will position the reader at the 
		///    open tag of the unknown element. This implies that if the first child XML element is unknown, this method 
		///    should return immediately and do nothing.
		/// 2) When all child XML elemnets are read. In this case, the reader will be positioned at the end tag of the parent element.
		/// 3) EOF.
		/// </remarks>
		/// <param name="serializationContext">Serialization context.</param>
		/// <param name="reader">XmlReader to read serialized data from.</param>
		/// <param name="element">In-memory ModelClass instance that will get the deserialized data.</param>
		private static void ReadChildElements(DslModeling::SerializationContext serializationContext, ModelClass element, global::System.Xml.XmlReader reader)
		{
			while (!serializationContext.Result.Failed && !reader.EOF && reader.NodeType == global::System.Xml.XmlNodeType.Element)
			{
				switch (reader.LocalName)
				{
					case "targets":	// Relationship "ManyToOneRelation"
						if (reader.IsEmptyElement)
						{	// No instance of this relationship, just skip
							DslModeling::SerializationUtilities.Skip(reader);
						}
						else
						{
							DslModeling::SerializationUtilities.SkipToFirstChild(reader);  // Skip the open tag of <targets>
							ReadManyToOneRelationInstances(serializationContext, element, reader);
							DslModeling::SerializationUtilities.Skip(reader);  // Skip the close tag of </targets>
						}
						break;
					case "properties":	// Relationship "ClassHasProperty"
						if (reader.IsEmptyElement)
						{	// No instance of this relationship, just skip
							DslModeling::SerializationUtilities.Skip(reader);
						}
						else
						{
							DslModeling::SerializationUtilities.SkipToFirstChild(reader);  // Skip the open tag of <properties>
							ReadClassHasPropertyInstances(serializationContext, element, reader);
							DslModeling::SerializationUtilities.Skip(reader);  // Skip the close tag of </properties>
						}
						break;
					case "manyToManyTargets":	// Relationship "ManyToManyRelation"
						if (reader.IsEmptyElement)
						{	// No instance of this relationship, just skip
							DslModeling::SerializationUtilities.Skip(reader);
						}
						else
						{
							DslModeling::SerializationUtilities.SkipToFirstChild(reader);  // Skip the open tag of <manyToManyTargets>
							ReadManyToManyRelationInstances(serializationContext, element, reader);
							DslModeling::SerializationUtilities.Skip(reader);  // Skip the close tag of </manyToManyTargets>
						}
						break;
					case "oneToOneTarget":	// Relationship "OneToOneRelation"
						if (reader.IsEmptyElement)
						{	// No instance of this relationship, just skip
							DslModeling::SerializationUtilities.Skip(reader);
						}
						else
						{
							DslModeling::SerializationUtilities.SkipToFirstChild(reader);  // Skip the open tag of <oneToOneTarget>
							ReadOneToOneRelationInstance(serializationContext, element, reader);
							DslModeling::SerializationUtilities.Skip(reader);  // Skip the close tag of </oneToOneTarget>
						}
						break;
					case "targetModelClasses":	// Relationship "InheritanceRelation"
						if (reader.IsEmptyElement)
						{	// No instance of this relationship, just skip
							DslModeling::SerializationUtilities.Skip(reader);
						}
						else
						{
							DslModeling::SerializationUtilities.SkipToFirstChild(reader);  // Skip the open tag of <targetModelClasses>
							ReadInheritanceRelationInstances(serializationContext, element, reader);
							DslModeling::SerializationUtilities.Skip(reader);  // Skip the close tag of </targetModelClasses>
						}
						break;
					default:
						return;  // Don't know this element.
				}
			}
		}
Exemple #6
0
        /// <summary>
        /// OnDragDrop is used to create classes corresponding to the selection dragged
        /// from the Server Explorer
        /// </summary>
        private void OnDragDrop(object sender, DragEventArgs e)
        {
            // Check if the data present is in the DSRef format
            if (e.Data.GetDataPresent(DSRefNavigator.DataSourceReferenceFormat))
            {
                try
                {
                    // Create a navigator for the DSRef Consumer (and dispose it when finished)
                    using (DSRefNavigator navigator = new DSRefNavigator(e.Data.GetData(
                                                                             DSRefNavigator.DataSourceReferenceFormat)
                                                                         as Stream))
                    {
                        _output = new OutputWindowHelper(DTEHelper.GetDTE(Store));

                        // Get connection info of the connection of selected tables
                        string        providerType = null;
                        IDbConnection connection   = ServerExplorerHelper.GetConnection(navigator, out providerType);

                        IDbHelper helper;

                        switch (providerType)
                        {
                        case "System.Data.SqlClient.SqlConnection":
                            helper = new SqlHelper(connection);
                            break;

                        case "System.Data.OracleClient.OracleConnection":
                        case "Oracle.DataAccess.Client.OracleConnection":
                            Log("Selecting Oracle Helper for provider " + providerType);
                            helper = new OracleHelper(connection);
                            break;

                        case "MySql.Data.MySqlClient.MySqlConnection":
                            helper = new MySqlHelper(connection);
                            break;

                        default:
                            // TODO: Support other databases with native providers.
                            Log(
                                string.Format(
                                    @"Failed: ActiveWriter does not support model generation through {0}. Supported providers: System.Data.SqlClient.SqlConnection, System.Data.OracleClient.OracleConnection, Oracle.DataAccess.Client.OracleConnection, MySql.Data.MySqlClient.MySqlConnection. You can help us improve this functionality, though. See http://www.castleproject.org/others/contrib/index.html to access ActiveWriter source code under the contrib repository, and check Dsl\ServerExplorerSupport\IDbHelper.cs for the start.",
                                    providerType));
                            return;
                        }

                        // Get the root element where we'll add the classes
                        Model model = Helper.GetModel(Store);
                        if (model == null)
                        {
                            Log("Failed: Cannot get the model for the store.");
                            return;
                        }

                        _manager = new DiagramManager(Store, model);
                        _manager.OutputWindow = _output;

                        // Create a transaction to add the clases.
                        using (Transaction txAdd =
                                   model.Store.TransactionManager.BeginTransaction("Add classes"))
                        {
                            List <DSRefNode> tableList = new List <DSRefNode>();
                            // Get the tables from the Server Explorer selection
                            // We'll iterate this list twice to use nodes' list to
                            // determine if we have to generate relations for each
                            // table or not.
                            foreach (DSRefNode node in navigator.ChildTableNodes)
                            {
                                tableList.Add(node);
                            }

                            _manager.Tables = tableList;

                            _relations = new List <Relation>();

                            foreach (DSRefNode node in tableList)
                            {
                                // Create the table and add it to the model
                                ModelClass cls = _manager.NewClass(node.Owner, node.Name);
                                PopulateClass(cls, connection, helper);
                                _manager.AssignModel(cls);
                            }

                            // Create relations
                            if (_relations != null && _relations.Count > 0)
                            {
                                HandleRelations();
                            }

                            // Commit the transaction and add tables to the model
                            txAdd.Commit();
                        }

                        // TODO: Auto layout doesn't work well. Will check with future versions of DSL tools.
                        // this.AutoLayoutShapeElements(this.NestedChildShapes);
                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.Message);
                }
                finally
                {
                    _manager   = null;
                    _relations = null;
                    _output    = null;
                }
            }
        }
Exemple #7
0
        private void PopulateClass(ModelClass cls, IDbConnection connection, IDbHelper helper)
        {
            if (cls != null && connection != null)
            {
                // Relations to this class (this class has the primary key)
                List <Relation> relationsTo = helper.GetPKRelations(cls);
                // If the other side of the relation (FK part) is not in our model, we won't
                // need the relation at all
                _manager.FilterPKRelations(relationsTo);

                // Relations from this class (this class has the foreign key)
                List <Relation> relationsFrom = helper.GetFKRelations(cls);
                // If the other side of the relation (PK part) is not in our model, we won't
                // need the relation at all
                _manager.FilterFKRelations(relationsFrom);

                // Properties
                List <Column> columns = helper.GetProperties(cls);
                if (columns != null && columns.Count > 0)
                {
                    List <Column> specialColumns  = new List <Column>();
                    List <Column> ordinaryColumns = new List <Column>();
                    foreach (Column column in columns)
                    {
                        if (column.Primary ||
                            (column.ForeignConstraints.Count > 0 &&
                             (Relation.GetCountOfMatchingRelations(relationsTo, column.ForeignConstraints) > 0 ||
                              Relation.GetCountOfMatchingRelations(relationsFrom, column.ForeignConstraints) > 0)
                            )
                            )
                        {
                            specialColumns.Add(column);
                        }
                        else
                        {
                            ordinaryColumns.Add(column);
                        }
                    }

                    if (_manager.SortProperties)
                    {
                        ordinaryColumns.Sort(new ColumnComparer());
                        specialColumns.Sort(new ColumnComparer());
                    }

                    // Keys
                    List <Column> primaryKeys = null;
                    if (specialColumns.Count > 0)
                    {
                        primaryKeys = Column.FindPrimaryKeys(specialColumns);
                        if (primaryKeys != null && primaryKeys.Count > 0)
                        {
                            // Create primary and composite keys
                            if (primaryKeys.Count == 1)
                            {
                                ModelProperty keyProperty = _manager.NewPrimaryKey(cls, primaryKeys[0]);
                                keyProperty.ColumnType = helper.GetNHibernateType(primaryKeys[0].DataType);
                                SetGenerator(keyProperty);
                            }
                            else
                            {
                                string keyClassName = cls.Name + Common.CompositeClassNameSuffix;
                                foreach (Column key in primaryKeys)
                                {
                                    ModelProperty keyProperty = _manager.NewCompositeKey(cls, key, keyClassName);
                                    keyProperty.ColumnType = helper.GetNHibernateType(key.DataType);
                                    SetGenerator(keyProperty);
                                }
                            }
                        }
                    }

                    foreach (var column in ordinaryColumns)
                    {
                        _manager.NewProperty(cls, column).ColumnType = helper.GetNHibernateType(column.DataType);
                    }

                    if (relationsTo != null && relationsTo.Count > 0)
                    {
                        foreach (Relation relation in relationsTo)
                        {
                            relation.PrimaryModelClass = cls;
                        }
                    }
                    _relations.AddRange(relationsTo);

                    if (relationsFrom != null && relationsFrom.Count > 0)
                    {
                        foreach (Relation relation in relationsFrom)
                        {
                            relation.ForeignModelClass = cls;
                        }
                        _relations.AddRange(relationsFrom);

                        // To define many to many and one to one, we need to know the pattern of foreign keys.
                        if (primaryKeys != null && primaryKeys.Count > 0)
                        {
                            foreach (Column key in primaryKeys)
                            {
                                Relation relation = Relation.GetForeginColumn(relationsFrom, key);
                                if (relation != null)
                                {
                                    relation.IsForeignColumnPrimary = true;
                                }
                            }
                        }
                    }
                }
            }
        }
		private void PopulateClass(ModelClass cls, IDbConnection connection, IDbHelper helper)
		{
			if (cls != null && connection != null)
			{
				// Relations to this class (this class has the primary key)
				List<Relation> relationsTo = helper.GetPKRelations(cls);
				// If the other side of the relation (FK part) is not in our model, we won't
				// need the relation at all
				_manager.FilterPKRelations(relationsTo);

				// Relations from this class (this class has the foreign key)
				List<Relation> relationsFrom = helper.GetFKRelations(cls);
				// If the other side of the relation (PK part) is not in our model, we won't
				// need the relation at all
				_manager.FilterFKRelations(relationsFrom);

				// Properties
				List<Column> columns = helper.GetProperties(cls);
				if (columns != null && columns.Count > 0)
				{
					List<Column> specialColumns = new List<Column>();
					List<Column> ordinaryColumns = new List<Column>();
					foreach(Column column in columns)
					{
						if (column.Primary ||
						    (column.ForeignConstraints.Count > 0 &&
						     (Relation.GetCountOfMatchingRelations(relationsTo, column.ForeignConstraints) > 0 ||
						      Relation.GetCountOfMatchingRelations(relationsFrom, column.ForeignConstraints) > 0)
						    )
							)
						{
							specialColumns.Add(column);
						}
						else
						{
						    ordinaryColumns.Add(column);
						}
					}

                    if (_manager.SortProperties)
                    {
                        ordinaryColumns.Sort(new ColumnComparer());
                        specialColumns.Sort(new ColumnComparer());
                    }

					// Keys
					List<Column> primaryKeys = null;
					if (specialColumns.Count > 0)
					{
						primaryKeys = Column.FindPrimaryKeys(specialColumns);
						if (primaryKeys != null && primaryKeys.Count > 0)
						{
							// Create primary and composite keys
							if (primaryKeys.Count == 1)
							{
								ModelProperty keyProperty = _manager.NewPrimaryKey(cls, primaryKeys[0]);
								keyProperty.ColumnType = helper.GetNHibernateType(primaryKeys[0].DataType);
								SetGenerator(keyProperty);
							}
							else
							{
								string keyClassName = cls.Name + Common.CompositeClassNameSuffix;
								foreach(Column key in primaryKeys)
								{
									ModelProperty keyProperty = _manager.NewCompositeKey(cls, key, keyClassName);
									keyProperty.ColumnType = helper.GetNHibernateType(key.DataType);
									SetGenerator(keyProperty);
								}
							}
						}
					}

                    foreach (var column in ordinaryColumns)
                    {
                        _manager.NewProperty(cls, column).ColumnType = helper.GetNHibernateType(column.DataType);
                    }

					if (relationsTo != null && relationsTo.Count > 0)
					{
						foreach(Relation relation in relationsTo)
						{
							relation.PrimaryModelClass = cls;
						}
					}
					_relations.AddRange(relationsTo);

					if (relationsFrom != null && relationsFrom.Count > 0)
					{
						foreach(Relation relation in relationsFrom)
						{
							relation.ForeignModelClass = cls;
						}
						_relations.AddRange(relationsFrom);

						// To define many to many and one to one, we need to know the pattern of foreign keys.
						if (primaryKeys != null && primaryKeys.Count > 0)
						{
							foreach(Column key in primaryKeys)
							{
								Relation relation = Relation.GetForeginColumn(relationsFrom, key);
								if (relation != null)
								{
									relation.IsForeignColumnPrimary = true;
								}
							}
						}
					}
				}
			}
		}