public void DefiningAndCustomizingVersionThroughBaseImplementation() { // In this example I'll show how you can work with Version and how ConfORM understands OOP var orm = new ObjectRelationalMapper(); var mapper = new Mapper(orm, new CoolPatternsAppliersHolder(orm)); // In this case I will use the definition of table-to-class strategy class by class orm.TablePerClass <CurrencyDefinition>(); orm.TablePerClass <Company>(); orm.TablePerClass <Customer>(); orm.TablePerClass <Provider>(); // Defining relations orm.OneToOne <Company, Customer>(); orm.OneToOne <Company, Provider>(); // In the follow line I'm defining which is the property used as Version for all classes inherited from VersionedEntity orm.VersionProperty <VersionedEntity>(ve => ve.Version); // In the follow line I'm customizing the column-name for the property used as Version for all classes inherited from VersionedEntity.... // Note : VersionedEntity is not an entity, it is only a base class. mapper.Class <VersionedEntity>(cm => cm.Version(ve => ve.Version, vm => vm.Column("Revision"))); // In the follow line I'm customizing the column-name for the property used as Version only for the class Provider // Note : You can move the follow line before the previous and the result does not change, this is because ConfORM can understand // which is a base customization and which is the specific customization. mapper.Class <Provider>(cm => cm.Version(ve => ve.Version, vm => vm.Column("IncrementalVersion"))); // Note : I have to create mappings for the whole domain; Entity and VersionedEntity are excluded from de mapping because out-side // root-entities hierarchy (root-entities are : CurrencyDefinition, Company, Customer, Provider) var mapping = mapper.CompileMappingFor(typeof(Entity).Assembly.GetTypes().Where(t => t.Namespace == typeof(Entity).Namespace)); Console.Write(mapping.AsString()); }
public void DefiningAndCustomizingVersionThroughBaseImplementation() { // In this example I'll show how you can work with Version and how ConfORM understands OOP var orm = new ObjectRelationalMapper(); var mapper = new Mapper(orm, new CoolPatternsAppliersHolder(orm)); // In this case I will use the definition of table-to-class strategy class by class orm.TablePerClass<CurrencyDefinition>(); orm.TablePerClass<Company>(); orm.TablePerClass<Customer>(); orm.TablePerClass<Provider>(); // Defining relations orm.OneToOne<Company, Customer>(); orm.OneToOne<Company, Provider>(); // In the follow line I'm defining which is the property used as Version for all classes inherited from VersionedEntity orm.VersionProperty<VersionedEntity>(ve=> ve.Version); // In the follow line I'm customizing the column-name for the property used as Version for all classes inherited from VersionedEntity.... // Note : VersionedEntity is not an entity, it is only a base class. mapper.Class<VersionedEntity>(cm => cm.Version(ve => ve.Version, vm => vm.Column("Revision"))); // In the follow line I'm customizing the column-name for the property used as Version only for the class Provider // Note : You can move the follow line before the previous and the result does not change, this is because ConfORM can understand // which is a base customization and which is the specific customization. mapper.Class<Provider>(cm => cm.Version(ve => ve.Version, vm => vm.Column("IncrementalVersion"))); // Note : I have to create mappings for the whole domain; Entity and VersionedEntity are excluded from de mapping because out-side // root-entities hierarchy (root-entities are : CurrencyDefinition, Company, Customer, Provider) var mapping = mapper.CompileMappingFor(typeof(Entity).Assembly.GetTypes().Where(t => t.Namespace == typeof(Entity).Namespace)); Console.Write(mapping.AsString()); }
public void ComposingPatternsAppliersPacks() { // Thanks to Lorenzo Vegetti to provide the domain of this example. // This example refers to a little-domain, interesting from the point of view of mapping with ConfORM. // Here you can see how apply general convetion, how and when compose patterns-appliers-packs and patterns-appliers, // how ConfORM can apply different mapping depending on the type of enum (see the difference on CostOptions) and so on... // You don't have to organize the mapping all in one class, as in this example, and you don't have to use the IModuleMapping... // You can organize the mapping as you feel more confortable for your application; in some case a class is enough, in other cases would // be better the separation per module/concern, you are not closed in "mapping per class" box. var orm = new ObjectRelationalMapper(); // With the follow line I'm adding the pattern for the POID strategy ("native" instead the default "High-Low") orm.Patterns.PoidStrategies.Add(new NativePoidPattern()); // composition of patterns-appliers-packs and patterns-appliers for Lorenzo's domain // Note: for bidirectional-one-to-many association Lorenzo is not interested in the default cascade behavior, // implemented in the BidirectionalOneToManyRelationPack, because he is using a sort of soft-delete in his base class VersionModelBase. // He can implements a custom pack of patterns-appliers to manage the situation when classes does not inherits from VersionModelBase by the way // he don't want the cascade atall, so the BidirectionalOneToManyInverseApplier will be enough IPatternsAppliersHolder patternsAppliers = (new SafePropertyAccessorPack()) .Merge(new OneToOneRelationPack(orm)) .Merge(new BidirectionalManyToManyRelationPack(orm)) .Merge(new DiscriminatorValueAsClassNamePack(orm)) .Merge(new CoolColumnsNamingPack(orm)) .Merge(new TablePerClassPack()) .Merge(new PluralizedTablesPack(orm, new EnglishInflector())) .Merge(new ListIndexAsPropertyPosColumnNameApplier()) .Merge(new BidirectionalOneToManyInverseApplier(orm)) .Merge(new EnumAsStringPack()) .Merge(new DatePropertyByNameApplier()) .Merge(new MsSQL2008DateTimeApplier()); // Instancing the Mapper using the result of Merge var mapper = new Mapper(orm, patternsAppliers); // Setting the version property using the base class orm.VersionProperty<VersionModelBase>(v => v.Version); // Note: I'm declaring the strategy only for the base entity orm.TablePerClassHierarchy<Cost>(); orm.TablePerClass<EditionQuotation>(); orm.TablePerClass<ProductQuotation>(); orm.TablePerClass<Quotation>(); AppliesGeneralConventions(mapper); // EditionQuotation.PrintCost don't use lazy-loading mapper.Customize<EditionQuotation>(map => map.ManyToOne(eq => eq.PrintCost, m2o => m2o.Lazy(LazyRelation.NoLazy))); // Customizes some others DDL's stuff outside conventions CustomizeColumns(mapper); // Note : I have to create mappings for the whole domain HbmMapping mapping = mapper.CompileMappingFor( typeof (GenericModelBase<>).Assembly.GetTypes().Where(t => t.Namespace == typeof (GenericModelBase<>).Namespace)); Console.Write(mapping.AsString()); }
private static HbmMapping GetMapping() { var orm = new ObjectRelationalMapper(); var mapper = new Mapper(orm, new CoolPatternsAppliersHolder(orm)); orm.TablePerClassHierarchy<Product>(); orm.TablePerClass<ActorRole>(); orm.Patterns.PoidStrategies.Add( new GuidOptimizedPoidPattern()); orm.VersionProperty<Entity>(x => x.Version); orm.NaturalId<Product>(p => p.Name); orm.Cascade<Movie, ActorRole>( Cascade.All | Cascade.DeleteOrphans); mapper.AddPropertyPattern(mi => mi.GetPropertyOrFieldType() == typeof(Decimal) && mi.Name.Contains("Price"), pm => pm.Type(NHibernateUtil.Currency)); mapper.AddPropertyPattern(mi => orm.IsRootEntity(mi.DeclaringType) && !"Description".Equals(mi.Name), pm => pm.NotNullable(true)); mapper.Subclass<Movie>(cm => cm.List(movie => movie.Actors, colm => colm.Index( lim => lim.Column("ActorIndex")), m => { })); var domainClasses = typeof(Entity).Assembly.GetTypes() .Where(t => typeof(Entity).IsAssignableFrom(t)); return mapper.CompileMappingFor(domainClasses); }
public void WhenExplicitDeclaredThenRecognizeVerion() { var orm = new ObjectRelationalMapper(); orm.VersionProperty<MyClass>(myclass => myclass.Version); orm.IsVersion(typeof (MyClass).GetProperty("Version")).Should().Be.True(); }
public void WhenExplicitDeclaredInBaseClassThenRecognizeVerion() { var orm = new ObjectRelationalMapper(); orm.VersionProperty <MyClass>(myclass => myclass.Version); orm.IsVersion(typeof(Inherited).GetProperty("Version")).Should().Be.True(); }
public void WhenVersionPropertyDefinedOnInterfaceThenRecognizeItOnConcreteClass() { var orm = new ObjectRelationalMapper(); orm.TablePerClass<MyVersionedEntityOnInterface>(); orm.VersionProperty<IVersionedEntity>(versionedEntity => versionedEntity.Version); orm.IsVersion(ForClass<MyVersionedEntityOnInterface>.Property(e => e.Version)).Should().Be.True(); }
public void WhenVersionPropertyDefinedOnInterfaceThenRecognizeItOnConcreteClass() { var orm = new ObjectRelationalMapper(); orm.TablePerClass <MyVersionedEntityOnInterface>(); orm.VersionProperty <IVersionedEntity>(versionedEntity => versionedEntity.Version); orm.IsVersion(ForClass <MyVersionedEntityOnInterface> .Property(e => e.Version)).Should().Be.True(); }
public void WhenCustomizedInterfaceThenWorkForConcreteImplementations() { var orm = new ObjectRelationalMapper(); // Mark the version property using the interface orm.VersionProperty <IVersionedEntity>(x => x.Version); orm.VersionProperty <ITimeVersionedEntity>(x => x.UpdatedAt); var rootEntities = new[] { typeof(MyEntity), typeof(MyOtherEntity) }; orm.TablePerClass(rootEntities); var mapper = new Mapper(orm); // customize base entities mapper.Class <IVersionedEntity>(cm => cm.Version(x => x.Version, vm => vm.Column("Revision"))); mapper.Class <ITimeVersionedEntity>(cm => cm.Version(x => x.UpdatedAt, vm => { vm.Column(column => { column.Name("LastUpdate"); column.NotNullable(true); column.SqlType("timestamp"); }); vm.Generated(VersionGeneration.Always); })); var mappings = mapper.CompileMappingFor(rootEntities); HbmClass hbmMyEntity = mappings.RootClasses.Single(hbm => hbm.Name == "MyEntity"); hbmMyEntity.Version.Should().Not.Be.Null(); hbmMyEntity.Version.name.Should().Be("Version"); hbmMyEntity.Version.column1.Should().Be("Revision"); HbmClass hbmMyOtherEntity = mappings.RootClasses.Single(hbm => hbm.Name == "MyOtherEntity"); hbmMyOtherEntity.Version.Should().Not.Be.Null(); hbmMyOtherEntity.Version.name.Should().Be("UpdatedAt"); hbmMyOtherEntity.Version.Columns.Single().name.Should().Be("LastUpdate"); hbmMyOtherEntity.Version.generated.Should().Be(HbmVersionGeneration.Always); }
public void WhenCustomizedInterfaceThenWorkForConcreteImplementations() { var orm = new ObjectRelationalMapper(); // Mark the version property using the interface orm.VersionProperty<IVersionedEntity>(x => x.Version); orm.VersionProperty<ITimeVersionedEntity>(x => x.UpdatedAt); var rootEntities = new[] { typeof(MyEntity), typeof(MyOtherEntity) }; orm.TablePerClass(rootEntities); var mapper = new Mapper(orm); // customize base entities mapper.Class<IVersionedEntity>(cm => cm.Version(x => x.Version, vm => vm.Column("Revision"))); mapper.Class<ITimeVersionedEntity>(cm => cm.Version(x => x.UpdatedAt, vm => { vm.Column(column => { column.Name("LastUpdate"); column.NotNullable(true); column.SqlType("timestamp"); }); vm.Generated(VersionGeneration.Always); })); var mappings = mapper.CompileMappingFor(rootEntities); HbmClass hbmMyEntity = mappings.RootClasses.Single(hbm => hbm.Name == "MyEntity"); hbmMyEntity.Version.Should().Not.Be.Null(); hbmMyEntity.Version.name.Should().Be("Version"); hbmMyEntity.Version.column1.Should().Be("Revision"); HbmClass hbmMyOtherEntity = mappings.RootClasses.Single(hbm => hbm.Name == "MyOtherEntity"); hbmMyOtherEntity.Version.Should().Not.Be.Null(); hbmMyOtherEntity.Version.name.Should().Be("UpdatedAt"); hbmMyOtherEntity.Version.Columns.Single().name.Should().Be("LastUpdate"); hbmMyOtherEntity.Version.generated.Should().Be(HbmVersionGeneration.Always); }
public void ComposingPatternsAppliersPacks() { // Thanks to Lorenzo Vegetti to provide the domain of this example. // This example refers to a little-domain, interesting from the point of view of mapping with ConfORM. // Here you can see how apply general convetion, how and when compose patterns-appliers-packs and patterns-appliers, // how ConfORM can apply different mapping depending on the type of enum (see the difference on CostOptions) and so on... // You don't have to organize the mapping all in one class, as in this example, and you don't have to use the IModuleMapping... // You can organize the mapping as you feel more confortable for your application; in some case a class is enough, in other cases would // be better the separation per module/concern, you are not closed in "mapping per class" box. var orm = new ObjectRelationalMapper(); // With the follow line I'm adding the pattern for the POID strategy ("native" instead the default "High-Low") orm.Patterns.PoidStrategies.Add(new NativePoidPattern()); // composition of patterns-appliers-packs and patterns-appliers for Lorenzo's domain // Note: for bidirectional-one-to-many association Lorenzo is not interested in the default cascade behavior, // implemented in the BidirectionalOneToManyRelationPack, because he is using a sort of soft-delete in his base class VersionModelBase. // He can implements a custom pack of patterns-appliers to manage the situation when classes does not inherits from VersionModelBase by the way // he don't want the cascade atall, so the BidirectionalOneToManyInverseApplier will be enough IPatternsAppliersHolder patternsAppliers = (new SafePropertyAccessorPack()) .Merge(new OneToOneRelationPack(orm)) .Merge(new BidirectionalManyToManyRelationPack(orm)) .Merge(new DiscriminatorValueAsClassNamePack(orm)) .Merge(new CoolColumnsNamingPack(orm)) .Merge(new TablePerClassPack()) .Merge(new PluralizedTablesPack(orm, new EnglishInflector())) .Merge(new ListIndexAsPropertyPosColumnNameApplier()) .Merge(new BidirectionalOneToManyInverseApplier(orm)) .Merge(new EnumAsStringPack()) .Merge(new DatePropertyByNameApplier()) .Merge(new MsSQL2008DateTimeApplier()); // Instancing the Mapper using the result of Merge var mapper = new Mapper(orm, patternsAppliers); // Setting the version property using the base class orm.VersionProperty <VersionModelBase>(v => v.Version); // Note: I'm declaring the strategy only for the base entity orm.TablePerClassHierarchy <Cost>(); orm.TablePerClass <EditionQuotation>(); orm.TablePerClass <ProductQuotation>(); orm.TablePerClass <Quotation>(); AppliesGeneralConventions(mapper); // EditionQuotation.PrintCost don't use lazy-loading mapper.Customize <EditionQuotation>(map => map.ManyToOne(eq => eq.PrintCost, m2o => m2o.Lazy(LazyRelation.NoLazy))); // Customizes some others DDL's stuff outside conventions CustomizeColumns(mapper); // Note : I have to create mappings for the whole domain HbmMapping mapping = mapper.CompileMappingFor( typeof(GenericModelBase <>).Assembly.GetTypes().Where(t => t.Namespace == typeof(GenericModelBase <>).Namespace)); Console.Write(mapping.AsString()); }