public EntityImpl() { Key = new EntityKeyImpl(); Generator = new EntityGenerator("assigned"); Cache = new Cache() { Include = Cache.IncludeTypes.All, Region = "", Usage = Cache.UsageTypes.None }; Discriminator = new Discriminator(); }
public Discriminator DeserialiseDiscriminator(XmlNode discriminatorNode) { NodeProcessor processor = new NodeProcessor(discriminatorNode); Discriminator discriminator = new Discriminator(); discriminator.AllowNull = processor.GetBool("AllowNull"); discriminator.ColumnName = processor.GetString("ColumnName"); discriminator.DiscriminatorType = (Enums.DiscriminatorTypes)Enum.Parse(typeof(Enums.DiscriminatorTypes), processor.GetString("DiscriminatorType"), true); discriminator.Force = processor.GetBool("Force"); discriminator.Formula = processor.GetString("Formula"); discriminator.Insert = processor.GetBool("Insert"); return(discriminator); }
public MappingSet GetEntities(IEnumerable<string> hbmFiles, ParseResults parseResults, IDatabase database) { EntitySet entities = new EntitySetImpl(); MappingSet mappingSet = new MappingSetImpl(database, entities); Dictionary<Class, ComponentSpecification> existingComponentSpecs = new Dictionary<Class, ComponentSpecification>(); List<hibernatemapping> mappingFiles = new List<hibernatemapping>(); List<ValidationEventArgs> mappingErrors = new List<ValidationEventArgs>(); List<NHibernateLoaderException.HbmXmlFile> errorFiles = new List<NHibernateLoaderException.HbmXmlFile>(); GetMappingFiles(hbmFiles, mappingFiles, mappingErrors, errorFiles); if (errorFiles.Count > 0) throw new NHibernateLoaderException(string.Format("Unsupported Elements found in HBM file."), errorFiles, mappingErrors); foreach (var hm in mappingFiles) { ArchAngel.Interfaces.SharedData.CurrentProject.SetUserOption("AutoImport", hm.autoimport); ArchAngel.Interfaces.SharedData.CurrentProject.SetUserOption("DefaultAccess", (TopLevelAccessTypes)Enum.Parse(typeof(TopLevelAccessTypes), hm.defaultaccess)); ArchAngel.Interfaces.SharedData.CurrentProject.SetUserOption("DefaultCascade", (TopLevelCascadeTypes)Enum.Parse(typeof(TopLevelCascadeTypes), hm.defaultcascade.Replace("-", "_"), true)); ArchAngel.Interfaces.SharedData.CurrentProject.SetUserOption("DefaultLazy", hm.defaultlazy); ArchAngel.Interfaces.SharedData.CurrentProject.SetUserOption("ProjectNamespace", hm.@namespace); foreach (var hClass in hm.Classes()) { Entity newEntity; string @namespace; string name; if (IsNameFullyQualified(hClass.name, out @namespace, out name)) { newEntity = new EntityImpl(name); string currentNamespace = ArchAngel.Interfaces.SharedData.CurrentProject.GetUserOption("ProjectNamespace") == null ? "" : ArchAngel.Interfaces.SharedData.CurrentProject.GetUserOption("ProjectNamespace").ToString(); if (string.IsNullOrWhiteSpace(currentNamespace)) ArchAngel.Interfaces.SharedData.CurrentProject.SetUserOption("ProjectNamespace", @namespace); } else newEntity = new EntityImpl(hClass.name); if (entities.GetEntity(newEntity.Name) != null) // This entity has already been added - the existing project probably has both HBM XML and Fluent mappings. continue; if (hClass.lazySpecified) newEntity.SetEntityLazy(hClass.lazy); else newEntity.SetEntityLazy(hm.defaultlazy); newEntity.SetEntitySqlWhereClause(hClass.where); newEntity.SetEntityDynamicInsert(hClass.dynamicinsert); newEntity.SetEntityDynamicUpdate(hClass.dynamicupdate); newEntity.SetEntityMutable(hClass.mutable); newEntity.SetEntityOptimisticLock((OptimisticLockModes)Enum.Parse(typeof(OptimisticLockModes), hClass.optimisticlock.ToString(), true)); newEntity.SetEntityProxy(hClass.proxy); newEntity.SetEntitySelectBeforeUpdate(hClass.selectbeforeupdate); newEntity.SetEntityBatchSize(hClass.batchsize); if (hClass.abstractSpecified) newEntity.IsAbstract = hClass.@abstract; newEntity.SetEntityPersister(hClass.persister); Mapping mapping = null; if (!newEntity.IsAbstract) mapping = CreateMappingFor(newEntity, hClass, database, hm.schema); entities.AddEntity(newEntity); if (mapping != null) mappingSet.AddMapping(mapping); #region Cache if (hClass.cache != null) { newEntity.Cache = new Cache(); switch (hClass.cache.include) { case cacheInclude.all: newEntity.Cache.Include = Cache.IncludeTypes.All; break; case cacheInclude.nonlazy: newEntity.Cache.Include = Cache.IncludeTypes.Non_Lazy; break; default: throw new NotImplementedException("Unexpected cache include value:" + hClass.cache.include.ToString()); } newEntity.Cache.Region = hClass.cache.region; switch (hClass.cache.usage) { case cacheUsage.nonstrictreadwrite: newEntity.Cache.Usage = Cache.UsageTypes.NonStrict_Read_Write; break; case cacheUsage.@readonly: newEntity.Cache.Usage = Cache.UsageTypes.Read_Only; break; case cacheUsage.readwrite: newEntity.Cache.Usage = Cache.UsageTypes.Read_Write; break; case cacheUsage.transactional: newEntity.Cache.Usage = Cache.UsageTypes.Transactional; break; default: throw new NotImplementedException("Unexpected cache usage value:" + hClass.cache.usage.ToString()); } } #endregion #region Discriminator if (hClass.discriminator != null) { ArchAngel.Providers.EntityModel.Model.EntityLayer.Discriminator d = new Discriminator() { AllowNull = !hClass.discriminator.notnull, ColumnName = hClass.discriminator.column, DiscriminatorType = string.IsNullOrWhiteSpace(hClass.discriminator.column) ? ArchAngel.Providers.EntityModel.Model.Enums.DiscriminatorTypes.Formula : ArchAngel.Providers.EntityModel.Model.Enums.DiscriminatorTypes.Column, Force = hClass.discriminator.force, Formula = hClass.discriminator.formula, Insert = hClass.discriminator.insert }; newEntity.Discriminator = d; newEntity.DiscriminatorValue = d.DiscriminatorType == Enums.DiscriminatorTypes.Column ? hClass.discriminator.column : hClass.discriminator.formula; //string columnName = hClass.discriminator.column; //throw new NotImplementedException("TODO: fixup discriminator stuff"); //Grouping g = new AndGrouping(); //IColumn column = newEntity.MappedTables().First().Columns.Single(c => c.Name == columnName); //ArchAngel.Providers.EntityModel.Model.DatabaseLayer.Discrimination.Operator op = ArchAngel.Providers.EntityModel.Model.DatabaseLayer.Discrimination.Operator.Equal; //string discriminatorValue = string.IsNullOrWhiteSpace(hClass.discriminatorvalue) ? "" : hClass.discriminatorvalue; //ExpressionValue value = new ExpressionValueImpl(discriminatorValue); //if (column != null && op != null && value != null) // g.AddCondition(new ConditionImpl(column, op, value)); //if (newEntity.Discriminator == null) // newEntity.Discriminator = new DiscriminatorImpl(); //newEntity.Discriminator.RootGrouping = g; } #endregion /////////////////////////////////////////////////// //foreach (var hProperty in hClass.Properties()) //{ // var property = CreateProperty(newEntity, mapping, hProperty); // SetPropertyInfoFromParsedCode(property, parseResults, hm.@namespace, mapping.FromTable.Schema, hClass.name); //} //foreach (var hComponent in hClass.Components()) //{ // ProcessComponent(hComponent, newEntity, mapping.FromTable, existingComponentSpecs, hm.@namespace, parseResults); //} /////////////////////////////////////////////////// id hId = hClass.Id(); if (hId != null) { var idProperty = CreateProperty(newEntity, mapping, hId); string schema = mapping == null ? null : mapping.FromTable.Schema; SetPropertyInfoFromParsedCode(idProperty, parseResults, hm.@namespace, schema, hClass.name); idProperty.IsKeyProperty = true; if (hId.generator == null) newEntity.Generator.ClassName = NHibernateHelper.MappingFiles.Version_2_2.GeneratorTypes.assigned.ToString(); else { newEntity.Generator.ClassName = hId.generator.@class; if (hId.generator.param != null) foreach (var param in hId.generator.param) newEntity.Generator.Parameters.Add(new EntityGenerator.Parameter(param.name, param.Text[0])); } } else { compositeid hCompId = hClass.CompositeId(); if (hCompId != null) { // Check if this is a component. If so, we need to do some additional processing. if (!string.IsNullOrEmpty(hCompId.@class)) { bool keyResult = ProcessComponentKey(hCompId, newEntity, mapping.FromTable, existingComponentSpecs, hm.@namespace, parseResults); if (keyResult == false) { // Fallback to composite key generation, log failure. ProcessCompositeKey(hm, hClass, newEntity, mapping, parseResults, hCompId); log.ErrorFormat("Could not create a component for composite key {0}", hCompId.name); } } else { // It is not a component. ProcessCompositeKey(hm, hClass, newEntity, mapping, parseResults, hCompId); } } } foreach (var hProperty in hClass.Properties()) { var property = CreateProperty(newEntity, mapping, hProperty); string schema = mapping == null ? null : mapping.FromTable.Schema; SetPropertyInfoFromParsedCode(property, parseResults, hm.@namespace, schema, hClass.name); property.SetPropertyFormula(hProperty.formula); property.SetPropertyGenerated((ArchAngel.Interfaces.NHibernateEnums.PropertyGeneratedTypes)Enum.Parse(typeof(ArchAngel.Interfaces.NHibernateEnums.PropertyGeneratedTypes), hProperty.generated.ToString())); if (hProperty.insertSpecified) property.SetPropertyInsert(hProperty.insert); property.SetPropertyOptimisticLock(hProperty.optimisticlock); if (hProperty.updateSpecified) property.SetPropertyUpdate(hProperty.update); } foreach (var hComponent in hClass.Components()) ProcessComponent(hComponent, newEntity, mapping.FromTable, existingComponentSpecs, hm.@namespace, parseResults); if (hClass.Version() != null) { // Create a property from the version node. ProcessVersionProperty(hm, hClass, newEntity, mapping, parseResults); } ProcessSubclasses(mappingSet, database, entities, newEntity, hClass.SubClasses(), hClass.schema.UnBackTick(), hClass.table.UnBackTick(), parseResults, hm.@namespace); ProcessJoinedSubclasses(mappingSet, database, entities, newEntity, hClass.JoinedSubClasses(), parseResults, hm.@namespace); ProcessUnionSubclasses(hClass, mappingSet, database, entities, newEntity, hClass.UnionSubClasses(), parseResults, hm.@namespace); } } List<string> processedClassNames = new List<string>(); // Second pass, to add missing foreign key columns and properties foreach (var hm in mappingFiles) { foreach (var hClass in hm.Classes()) { string className; if (!IsNameFullyQualified(hClass.name, out className)) className = hClass.name; if (processedClassNames.Contains(className)) continue; processedClassNames.Add(className); foreach (var hManyToOne in hClass.ManyToOnes()) { var fkColumnNames = ReferenceLoader.GetColumnNames(hManyToOne.column, hManyToOne.Columns()).ToList(); Entity entity = entities.Entities.Single(e => e.Name == className); bool found = false; foreach (var prop in entity.Properties) { IColumn mappedColumn = prop.MappedColumn(); if (mappedColumn != null) { string mappedColumnName = null; if (hManyToOne.column != null) mappedColumnName = hManyToOne.column; else if (hManyToOne.Columns().Count > 0) mappedColumnName = hManyToOne.Columns()[0].name; if (!string.IsNullOrEmpty(mappedColumnName) && mappedColumn.Name == mappedColumnName.UnBackTick()) { found = true; break; } } //else //{ // string gfh2 = string.Format("{0}.{1}", hClass.name, hManyToOne.column1.UnBackTick()); // gfh2 = ""; // // TODO: we should create a column for this property // Entity referencedEntity = entities.Entities.Single(e => e.Name == hManyToOne.@class); // Property referencedProperty = referencedEntity.Key.Properties.ElementAt(0); // IColumn tempColumn = referencedProperty.MappedColumn(); // IColumn newColumn = ArchAngel.Providers.EntityModel.Controller.MappingLayer.OneToOneEntityProcessor.CreateColumnFromProperty(referencedProperty); // newColumn.Name = hManyToOne.column1.UnBackTick(); // ITable table = entity.MappedTables().First(); // table.AddColumn(newColumn); // prop.SetMappedColumn(newColumn); //} } if (!found) { string name; string manyToOneClassName = hManyToOne.@class != null ? hManyToOne.@class : hManyToOne.name; IsNameFullyQualified(manyToOneClassName, out name); Entity referencedEntity = entities.Entities.Single(e => e.Name == name); Property referencedProperty = referencedEntity.Key.Properties.ElementAt(0); IColumn newColumn = null; foreach (Table t in entity.MappedTables()) { string colName = null; if (hManyToOne.column != null) colName = hManyToOne.column; else if (hManyToOne.Columns().Count > 0) colName = hManyToOne.Columns()[0].name; newColumn = t.Columns.SingleOrDefault(c => !string.IsNullOrEmpty(colName) && c.Name == colName.UnBackTick()); if (newColumn != null) break; } if (newColumn == null) { newColumn = ArchAngel.Providers.EntityModel.Controller.MappingLayer.OneToOneEntityProcessor.CreateColumnFromProperty(referencedProperty); ITable table = entity.MappedTables().First(); table.AddColumn(newColumn); } Property newProperty = ArchAngel.Providers.EntityModel.Controller.MappingLayer.OneToOneEntityProcessor.CreatePropertyFromColumn(newColumn); //entity.Properties.SingleOrDefault(p => p.MappedColumn() == entity.AddProperty(newProperty); } //ITable table = entity.MappedTables().First(); } } } // Second pass, for references. var refProcessor = new ReferenceLoader(); refProcessor.ProcessReferences(mappingFiles, mappingSet); processedClassNames.Clear(); // Second pass, to add missing foreign key columns and properties foreach (var hm in mappingFiles) { foreach (var hClass in hm.Classes()) { string className; IsNameFullyQualified(hClass.name, out className); if (processedClassNames.Contains(className)) continue; processedClassNames.Add(className); foreach (var hManyToOne in hClass.ManyToOnes()) { var fkColumnNames = ReferenceLoader.GetColumnNames(hManyToOne.column, hManyToOne.Columns()).ToList(); Entity entity = entities.Entities.Single(e => e.Name == className); foreach (var prop in entity.Properties) { IColumn mappedColumn = prop.MappedColumn(); if (mappedColumn == null) { // TODO: we should create a column for this property string manyToOneClassName; IsNameFullyQualified(hManyToOne.@class, out manyToOneClassName); Entity referencedEntity = entities.Entities.Single(e => e.Name == manyToOneClassName); Property referencedProperty = referencedEntity.Key.Properties.ElementAt(0); IColumn tempColumn = referencedProperty.MappedColumn(); IColumn newColumn = ArchAngel.Providers.EntityModel.Controller.MappingLayer.OneToOneEntityProcessor.CreateColumnFromProperty(referencedProperty); string newColName = ""; if (hManyToOne.column != null) newColName = hManyToOne.column; else if (hManyToOne.Columns().Count > 0) newColName = hManyToOne.Columns()[0].name; newColumn.Name = newColName.UnBackTick(); ITable table = entity.MappedTables().First(); if (table.Columns.Count(c => c.Name == newColumn.Name) == 0) table.AddColumn(newColumn); else newColumn = table.Columns.First(c => c.Name == newColumn.Name); prop.SetMappedColumn(newColumn); } } } } } return mappingSet; }