Exemplo n.º 1
0
        private void UseDiscoveredInformationToCreateReferences(MappingSet mappingSet)
        {
            while (associationInformation.Count > 0)
            {
                var info = associationInformation[0];
                associationInformation.RemoveAt(0);
                // Get existing objects
                var fromEntity = mappingSet.EntitySet.GetEntity(info.ThisEntityName);
                var fromTable  = fromEntity.MappedTables().First();
                var toEntity   = mappingSet.EntitySet.GetEntity(info.OtherEntityName);
                var toTable    = toEntity.MappedTables().First();

                // Sort out this side of the reference.
                Reference reference = new ReferenceImpl();
                reference.Entity1      = fromEntity;
                reference.End1Name     = info.PropertyName;
                reference.End1Enabled  = true;
                reference.Cardinality1 = info.Cardinality;
                reference.SetEnd1AssociationType(info.AssociationType);
                reference.SetEnd1IndexColumnName(info.IndexColumn);
                reference.SetEnd1SqlWhereClause(info.WhereClause);
                reference.SetReferenceEnd1FetchMode(info.FetchMode);
                reference.SetReferenceEnd1CollectionFetchMode(info.CollectionFetchMode);
                reference.SetReferenceEnd1Insert(info.Insert);
                reference.SetReferenceEnd1Update(info.Update);
                reference.SetReferenceEnd1Inverse(info.Inverse);
                reference.SetReferenceEnd1FetchMode(info.FetchMode);
                reference.SetReferenceEnd1Lazy(info.CollectionLazy);
                reference.SetReferenceEnd1Cascade(info.Cascade);
                reference.SetReferenceEnd1CollectionCascade(info.CollectionCascade);

                if (!string.IsNullOrWhiteSpace(info.OrderByColumnName))
                {
                    var orderByProp = fromEntity.Properties.SingleOrDefault(p => p.MappedColumn() != null && p.MappedColumn().Name.Equals(info.OrderByColumnName, StringComparison.InvariantCultureIgnoreCase));

                    if (orderByProp != null)
                    {
                        reference.SetReferenceEnd1OrderByProperty(orderByProp.Name);
                    }
                }
                reference.SetReferenceEnd1OrderByIsAsc(info.OrderByIsAsc);
                // Find the other side of the reference.
                ProcessOtherEndOfReference(info, toEntity, reference);
                //associationInformation.RemoveAt(0);
                fromEntity.AddReference(reference);

                if (fromEntity.InternalIdentifier != toEntity.InternalIdentifier)
                {
                    toEntity.AddReference(reference);
                }

                if (info.AssociationTableName != null &&
                    !string.IsNullOrEmpty(info.AssociationTableName.TableName))
                {
                    // Map Reference to Table
                    string schema      = /*string.IsNullOrEmpty(info.AssociationTableName.SchemaName) ? "" :*/ info.AssociationTableName.SchemaName.UnBackTick();
                    var    mappedTable = mappingSet.Database.GetTable(info.AssociationTableName.TableName.UnBackTick(), schema);

                    if (mappedTable == null)
                    {
                        throw new NHibernateMappingException(string.Format("Could not find association table {0} to map to reference {1}.", info.AssociationTableName, reference.Name));
                    }

                    mappingSet.ChangeMappingFor(reference).To(mappedTable);
                }
                else
                {
                    IEnumerable <IColumn>             foreignKeyColumns;
                    Func <DirectedRelationship, bool> predicate;

                    if (info.ForeignKeyColumnNames.Count == 0 && info.Cardinality.Start == 1 && info.Cardinality.End == 1 && fromTable != toTable)
                    {
                        predicate = r =>
                                    r.ToKey.Columns.OrderBy(c => c.Name).SequenceEqual(r.ToTable.ColumnsInPrimaryKey.OrderBy(c => c.Name)) &&
                                    r.FromKey.Columns.OrderBy(c => c.Name).SequenceEqual(r.FromTable.ColumnsInPrimaryKey.OrderBy(c => c.Name));
                    }
                    else
                    {
                        if (info.ForeignKeyBelongsToThisTable)
                        {
                            foreignKeyColumns = info.ForeignKeyColumnNames.Select(f => fromTable.GetColumn(f.UnBackTick()));

                            if (fromTable == toTable)
                            {
                                // Self referencing keys might have the primary key at either end.
                                predicate = r => (r.FromKey.Columns.SequenceEqual(foreignKeyColumns) || r.ToKey.Columns.SequenceEqual(foreignKeyColumns));
                            }
                            else
                            {
                                predicate = r => r.FromKey.Columns.SequenceEqual(foreignKeyColumns);
                            }
                        }
                        else
                        {
                            foreignKeyColumns = info.ForeignKeyColumnNames.Select(f => toTable.GetColumn(f.UnBackTick()));
                            predicate         = r => r.ToKey.Columns.SequenceEqual(foreignKeyColumns);
                        }
                    }
                    var possibleRelationships = fromTable.DirectedRelationships.Where(r => r.ToTable == toTable);
                    var relationshipToMap     = possibleRelationships.FirstOrDefault(predicate);

                    if (relationshipToMap != null)
                    {
                        mappingSet.ChangeMappingFor(reference).To(relationshipToMap.Relationship);
                    }
                    else
                    {
                        throw new NHibernateMappingException(string.Format("Could not find relationship to map to for reference between Entities \"{0}\" and \"{1}\"", info.ThisEntityName, info.OtherEntityName));
                    }
                }
            }
        }