public void WhenExplicitDeclaredThenMatchWithCollectionProperty() { var mi = typeof(EntityWithSets).GetProperty("Others"); var autoinspector = new SimpleModelInspector(); var mapper = new ModelMapper(autoinspector); mapper.Class <EntityWithSets>(map => map.Set(x => x.Others, x => { }, y => {})); var inspector = (IModelInspector)autoinspector; Assert.That(inspector.IsSet(mi), Is.True); }
public void IncludesFieldsWhenExplicitDeclared() { var autoinspector = new SimpleModelInspector(); var mapper = new ModelMapper(autoinspector); mapper.Class <MyEntity>(map => map.Property("pizza", x => { })); var inspector = (IModelInspector)autoinspector; var pi = typeof(MyEntity).GetField("pizza", BindingFlags.Instance | BindingFlags.NonPublic); Assert.That(inspector.IsPersistentProperty(pi), Is.True); }
public void IncludesNoReadOnly() { var autoinspector = new SimpleModelInspector(); var inspector = (IModelInspector)autoinspector; PropertyInfo pi = typeof(MyEntity).GetProperty("NoReadOnly"); Assert.That(inspector.IsPersistentProperty(pi), Is.True); pi = typeof(MyEntity).GetProperty("WriteOnly"); Assert.That(inspector.IsPersistentProperty(pi), Is.True); }
public void WhenExplicitlyDeclaredAsUnionSubclassThenIsNotTablePerClass() { var autoinspector = new SimpleModelInspector(); var mapper = new ModelMapper(autoinspector); mapper.Class <MyClass>(x => { }); mapper.UnionSubclass <Inherited>(x => { }); var inspector = (IModelInspector)autoinspector; Assert.That(inspector.IsTablePerClass(typeof(MyClass)), Is.False); Assert.That(inspector.IsTablePerClass(typeof(Inherited)), Is.False); }
public void WhenNotExplicitlyDeclaredMatchDefaultDelegate() { var autoinspector = new SimpleModelInspector(); var inspector = (IModelInspector)autoinspector; Assert.That(inspector.IsPersistentId(typeof(TestEntity).GetProperty("Id")), Is.True); Assert.That(inspector.IsPersistentId(typeof(TestEntity).GetProperty("id")), Is.True); Assert.That(inspector.IsPersistentId(typeof(TestEntity).GetProperty("PoId")), Is.True); Assert.That(inspector.IsPersistentId(typeof(TestEntity).GetProperty("POID")), Is.True); Assert.That(inspector.IsPersistentId(typeof(TestEntity).GetProperty("OId")), Is.True); Assert.That(inspector.IsPersistentId(typeof(TestEntity).GetProperty("TestEntityId")), Is.True); }
public void WhenExplicitlyDeclaredAsSubclassThenIsNotTablePerClass() { var autoinspector = new SimpleModelInspector(); var mapper = new ModelMapper(autoinspector); mapper.Class <MyClass>(x => { }); mapper.Subclass <Inherited>(x => { }); var inspector = (IModelInspector)autoinspector; inspector.IsTablePerClass(typeof(MyClass)).Should().Be.False(); inspector.IsTablePerClass(typeof(Inherited)).Should().Be.False(); }
public void WhenDictionaryUnidirectionalDeclaredManyToManyThenNoMatch() { var autoinspector = new SimpleModelInspector(); var mapper = new ModelMapper(autoinspector); mapper.Class <MyClass>(map => map.Bag(x => x.DicRelateds, cm => { }, relMap => relMap.ManyToMany())); mapper.Class <Related>(x => { }); mapper.Class <Bidirectional>(x => { }); var inspector = (IModelInspector)autoinspector; var pi = Mapping.ByCode.TypeExtensions.DecodeMemberAccessExpression <MyClass>(x => x.DicRelateds); Assert.That(inspector.IsOneToMany(pi), Is.False); }
public void WhenMapPropertiesInTheBaseJumpedClassUsingMemberNameThenMapInInherited() { // ignoring MyClass and using Inherited, as root-class, I will try to map all properties using the base class. // NH have to recognize the case and map those properties in the inherited. var inspector = new SimpleModelInspector(); inspector.IsEntity((type, declared) => type == typeof(Inherited)); inspector.IsRootEntity((type, declared) => type == typeof(Inherited)); var mapper = new ModelMapper(inspector); mapper.Class <MyClass>(mc => { mc.Id(x => x.Id); mc.Property("Simple", map => map.Access(Accessor.Field)); mc.Property("ComplexType", map => map.Access(Accessor.Field)); mc.Bag <string>("Bag", y => y.Access(Accessor.Field)); mc.IdBag <MyCompo>("IdBag", y => y.Access(Accessor.Field)); mc.List <string>("List", y => y.Access(Accessor.Field)); mc.Set <string>("Set", y => y.Access(Accessor.Field)); mc.Map <int, string>("Map", y => y.Access(Accessor.Field)); mc.OneToOne <Related>("OneToOne", y => y.Access(Accessor.Field)); mc.ManyToOne <Related>("ManyToOne", y => y.Access(Accessor.Field)); mc.Any <object>("Any", typeof(int), y => y.Access(Accessor.Field)); mc.Component("DynamicCompo", new { A = 2 }, y => y.Access(Accessor.Field)); mc.Component <MyCompo>("Compo", y => { y.Access(Accessor.Field); y.Property(c => c.Something); }); }); mapper.Class <Inherited>(mc => { }); HbmMapping mappings = mapper.CompileMappingForAllExplicitAddedEntities(); HbmClass hbmClass = mappings.RootClasses[0]; mappings.JoinedSubclasses.Should().Be.Empty(); hbmClass.Properties.Select(p => p.Name).Should().Have.SameValuesAs("Simple", "ComplexType", "Bag", "IdBag", "List", "Set", "Map", "Compo", "OneToOne", "ManyToOne", "Any", "DynamicCompo"); hbmClass.Properties.Select(p => p.Access).All(x => x.Satisfy(access => access.Contains("field."))); }
public void WhenMapPropertiesInTheBaseJumpedClassThenMapInInherited() { // ignoring MyClass and using Inherited, as root-class, I will try to map all properties using the base class. // NH have to recognize the case and map those properties in the inherited. var inspector = new SimpleModelInspector(); inspector.IsEntity((type, declared) => type == typeof(Inherited)); inspector.IsRootEntity((type, declared) => type == typeof(Inherited)); var mapper = new ModelMapper(inspector); mapper.Class <MyClass>(mc => { mc.Id(x => x.Id); mc.Property(x => x.Simple, map => map.Access(Accessor.Field)); mc.Property(x => x.ComplexType, map => map.Access(Accessor.Field)); mc.Bag(x => x.Bag, y => y.Access(Accessor.Field)); mc.IdBag(x => x.IdBag, y => y.Access(Accessor.Field)); mc.List(x => x.List, y => y.Access(Accessor.Field)); mc.Set(x => x.Set, y => y.Access(Accessor.Field)); mc.Map(x => x.Map, y => y.Access(Accessor.Field)); mc.OneToOne(x => x.OneToOne, y => y.Access(Accessor.Field)); mc.ManyToOne(x => x.ManyToOne, y => y.Access(Accessor.Field)); mc.Any(x => x.Any, typeof(int), y => y.Access(Accessor.Field)); mc.Component(x => x.DynamicCompo, new { A = 2 }, y => y.Access(Accessor.Field)); mc.Component(x => x.Compo, y => { y.Access(Accessor.Field); y.Property(c => c.Something); }); }); mapper.Class <Inherited>(mc => {}); var mappings = mapper.CompileMappingForAllExplicitlyAddedEntities(); var hbmClass = mappings.RootClasses[0]; Assert.That(mappings.JoinedSubclasses, Is.Empty); Assert.That(hbmClass.Properties.Select(p => p.Name), Is.EquivalentTo(new [] { "Simple", "ComplexType", "Bag", "IdBag", "List", "Set", "Map", "Compo", "OneToOne", "ManyToOne", "Any", "DynamicCompo" })); Assert.That(hbmClass.Properties.Select(p => p.Access).All(x => x.StartsWith("field.")), Is.True); }
/// <summary> /// Returns true if the property is persisted to the DB /// </summary> /// <param name="prop"></param> /// <returns></returns> public static bool IsPersistentProperty(MemberInfo prop) { if (!MappingHelper.IsPersistentProperty(prop)) { return(false); } if (!MappingHelper.IsRootEntity(prop.DeclaringType) && prop.DeclaringType.BaseType != null) { var upperLevelProperty = prop.DeclaringType.BaseType.GetProperty(prop.Name); if (upperLevelProperty != null) { if (MappingHelper.GetColumnName(prop) == MappingHelper.GetColumnName(upperLevelProperty)) { return(false); } } } var inspector = new SimpleModelInspector() as IModelInspector; return(inspector.IsPersistentProperty(prop)); }
public void Init(string connectionStringName = "local", bool debug = false, string database = "") { //ilmerge //если сборки объединены то логика определения системы протоколирование не работает //нужно вручную настроить ее LoggerProvider.SetLoggersFactory(new Log4NetLoggerFactory()); var mappingDialect = new MySQL5Dialect(); var mapper = new ConventionModelMapper(); var baseInspector = new SimpleModelInspector(); var simpleModelInspector = ((SimpleModelInspector)mapper.ModelInspector); simpleModelInspector.IsPersistentProperty((m, declared) => { return(((IModelInspector)baseInspector).IsPersistentProperty(m) && m.GetCustomAttributes(typeof(IgnoreAttribute), false).Length == 0); }); simpleModelInspector.IsRootEntity((type, declared) => { var modelInspector = ((IModelInspector)simpleModelInspector); return(declared || (type.IsClass && type.BaseType != null //если наследуемся от класса который не маплен то это простое наследование && (typeof(object) == type.BaseType || !modelInspector.IsEntity(type.BaseType)) || type.BaseType == typeof(BaseStatelessObject)) && modelInspector.IsEntity(type)); }); Index <Waybill>(w => w.WriteTime); Index <WaybillLine>(w => w.ProductId); Index <WaybillLine>(w => w.ProducerId); Index <WaybillLine>(w => w.Product); Index <WaybillLine>(w => w.SerialNumber); Index <WaybillLine>(w => w.RejectId); Index <WaybillLine>(w => w.EAN13); Index <Reject>(w => w.ProductId); Index <Reject>(w => w.ProducerId); Index <Reject>(w => w.Product); Index <Reject>(w => w.Series); Index <Offer>(o => o.ProductId); Index <Offer>(o => o.CatalogId); //индекс для восстановления заявок Index <Offer>(o => o.ProductSynonymId); Index <Offer>(o => o.PriceId); Index <Offer>(o => o.Id.RegionId); Index <SentOrder>(o => o.SentOn); Index <SentOrder>(o => o.ServerId); Index <DeletedOrder>(o => o.DeletedOn); Index <DeletedOrder>(o => o.ServerId); Index <MinCost>(r => r.Diff); Index <Catalog>(r => r.Name); Index <Drug>(r => r.EAN); Index <BarCode>(r => r.Value); Index <BarcodeProducts>(x => x.Barcode); mapper.Class <Drug>(x => x.Id(y => y.DrugId)); mapper.Class <Settings>(m => { m.Bag(o => o.Markups, c => { c.Inverse(true); c.Cascade(Cascade.DeleteOrphans | Cascade.All); }); m.Bag(o => o.PriceTags, c => { c.Inverse(true); c.Cascade(Cascade.DeleteOrphans | Cascade.All); }); m.Bag(o => o.Waybills, c => c.Cascade(Cascade.DeleteOrphans | Cascade.All)); m.Property(x => x.ClientTokenV2, c => c.Length(10000)); }); mapper.Class <MarkupConfig>(m => { m.Property(o => o.Begin, om => om.Access(Accessor.Field)); m.Property(o => o.End, om => om.Access(Accessor.Field)); }); mapper.Class <PriceTagSettings>(o => { o.Id(r => r.Id); }); mapper.Class <PriceTag>(m => { m.Bag(o => o.Items, c => { c.Inverse(true); c.Cascade(Cascade.DeleteOrphans | Cascade.All); }); }); mapper.Class <PriceTagItem>(o => { o.Id(r => r.Id); }); mapper.Class <MinOrderSumRule>(m => { m.ComposedId(c => { c.ManyToOne(p => p.Address); c.ManyToOne(p => p.Price, t => t.Columns(cm => cm.Name("PriceId"), cm => cm.Name("RegionId"))); }); m.Property(p => p.MinOrderSum); }); mapper.Class <Limit>(m => { m.ComposedId(c => { c.ManyToOne(p => p.Address); c.ManyToOne(p => p.Price, t => t.Columns(cm => cm.Name("PriceId"), cm => cm.Name("RegionId"))); }); m.Property(p => p.Value); }); mapper.Class <WaybillOrder>(m => { m.ComposedId(c => { c.Property(p => p.OrderLineId); c.Property(p => p.DocumentLineId); }); }); mapper.Class <Promotion>(m => { m.Bag(o => o.Catalogs, c => { c.Table("PromotionCatalogs"); c.Key(km => km.Column("PromotionId")); }, cm => { cm.ManyToMany(km => km.Column("CatalogId")); }); }); mapper.Class <ProducerPromotion>(m => { m.Bag(o => o.Catalogs, c => { c.Table("ProducerPromotionCatalogs"); c.Key(km => km.Column("PromotionId")); }, cm => { cm.ManyToMany(km => km.Column("CatalogId")); }); }); mapper.Class <ProducerPromotion>(m => { m.Bag(o => o.Suppliers, c => { c.Table("ProducerPromotionSuppliers"); c.Key(km => km.Column("PromotionId")); }, cm => { cm.ManyToMany(km => km.Column("SupplierId")); }); }); mapper.Class <Price>(m => { m.ComponentAsId(c => c.Id); m.Property(p => p.ContactInfo, c => c.Length(10000)); m.Property(p => p.OperativeInfo, c => c.Length(10000)); m.Property(p => p.RegionId, c => c.Insert(false)); m.Version(p => p.Timestamp, c => { c.Type(new TimestampType()); c.Column(cc => cc.Default("'0001-01-01 00:00:00'")); }); }); mapper.Class <Check>(m => { m.Property(x => x.ServerId, p => p.UniqueKey("ServerIdUniq")); }); mapper.Class <Mail>(m => { m.Property(p => p.Subject, c => c.Length(10000)); m.Property(p => p.Body, c => c.Length(10000)); }); mapper.Class <Order>(m => { m.Property(o => o.Frozen, om => om.Access(Accessor.Field)); m.ManyToOne(o => o.MinOrderSum, c => { c.Columns(cm => cm.Name("AddressId"), cm => cm.Name("PriceId"), cm => cm.Name("RegionId")); c.Insert(false); c.Update(false); }); m.ManyToOne(o => o.Limit, c => { c.Columns(cm => cm.Name("AddressId"), cm => cm.Name("PriceId"), cm => cm.Name("RegionId")); c.Insert(false); c.Update(false); }); m.Bag(o => o.Lines, c => { c.Cascade(Cascade.DeleteOrphans | Cascade.All); c.Inverse(true); }); }); mapper.Class <Waybill>(m => { //при миграции могут если поставщик отсутствует nhibernate будет перезаписывать m.ManyToOne(x => x.Address, x => x.Update(false)); m.ManyToOne(x => x.Supplier, x => x.Update(false)); m.Bag(o => o.Lines, c => { c.Cascade(Cascade.DeleteOrphans | Cascade.All); c.Inverse(true); }); }); mapper.Class <WaybillLine>(m => { m.Property(l => l.RetailCost, p => p.Access(Accessor.Field)); m.Property(l => l.RetailMarkup, p => p.Access(Accessor.Field)); m.Property(l => l.RealRetailMarkup, p => p.Access(Accessor.Field)); m.Property(l => l.MaxRetailMarkup, p => p.Access(Accessor.Field)); m.Bag(l => l.CertificateFiles, c => { c.Cascade(Cascade.DeleteOrphans | Cascade.All); }); }); mapper.Class <Address>(m => m.Bag(o => o.Orders, c => { c.Cascade(Cascade.All | Cascade.DeleteOrphans); c.Inverse(true); })); mapper.Class <InventoryDoc>(m => { m.Property(x => x.ServerId, p => p.UniqueKey("ServerIdUniq")); m.Bag(o => o.Lines, c => { c.Cascade(Cascade.All | Cascade.DeleteOrphans); }); }); mapper.Class <InventoryLine>(m => { m.ManyToOne(x => x.Stock, p => p.Cascade(Cascade.Refresh)); }); mapper.Class <UnpackingDoc>(m => { m.Property(x => x.ServerId, p => p.UniqueKey("ServerIdUniq")); //m.Bag(o => o.Lines, c => { //c.Cascade(Cascade.All | Cascade.DeleteOrphans); //}); }); mapper.Class <UnpackingLine>(m => { m.ManyToOne(x => x.DstStock, p => p.Cascade(Cascade.All)); m.ManyToOne(x => x.SrcStock, p => p.Cascade(Cascade.All)); }); mapper.Class <WriteoffDoc>(m => { m.Property(x => x.ServerId, p => p.UniqueKey("ServerIdUniq")); m.Bag(o => o.Lines, c => { c.Cascade(Cascade.All | Cascade.DeleteOrphans); }); }); mapper.Class <ReturnDoc>(m => { m.Property(x => x.ServerId, p => p.UniqueKey("ServerIdUniq")); m.Bag(o => o.Lines, c => { c.Cascade(Cascade.All | Cascade.DeleteOrphans); }); }); mapper.Class <DisplacementDoc>(m => { m.Property(x => x.ServerId, p => p.UniqueKey("ServerIdUniq")); m.Bag(o => o.Lines, c => { c.Cascade(Cascade.All | Cascade.DeleteOrphans); }); }); mapper.Class <DisplacementLine>(m => { m.ManyToOne(x => x.SrcStock, p => p.Cascade(Cascade.Refresh)); m.ManyToOne(x => x.DstStock, p => p.Cascade(Cascade.All)); }); mapper.Class <ReassessmentDoc>(m => { m.Property(x => x.ServerId, p => p.UniqueKey("ServerIdUniq")); m.Bag(o => o.Lines, c => { c.Cascade(Cascade.All | Cascade.DeleteOrphans); }); }); mapper.Class <ReassessmentLine>(m => m.ManyToOne(x => x.DstStock, p => p.Cascade(Cascade.All))); mapper.Class <Offer>(m => { m.ManyToOne(o => o.Price, c => { c.Insert(false); c.Update(false); }); m.ManyToOne(o => o.LeaderPrice, c => c.Columns(cm => cm.Name("LeaderPriceId"), cm => cm.Name("LeaderRegionId"))); }); mapper.Class <OrderLine>(m => { m.Property(l => l.RetailMarkup, p => p.Access(Accessor.Field)); m.Property(l => l.RetailCost, p => p.Access(Accessor.Field)); }); mapper.Class <SentOrder>(m => { m.Bag(o => o.Lines, c => { c.Key(k => k.Column("OrderId")); c.Cascade(Cascade.DeleteOrphans | Cascade.All); c.Inverse(true); }); }); mapper.Class <DeletedOrder>(m => { m.Bag(o => o.Lines, c => { c.Key(k => k.Column("OrderId")); c.Cascade(Cascade.DeleteOrphans | Cascade.All); c.Inverse(true); }); }); mapper.Class <Mail>(m => { m.Bag(o => o.Attachments, c => { c.Cascade(Cascade.DeleteOrphans | Cascade.All); }); }); mapper.Class <BatchLine>(m => { m.Property(l => l.Comment, c => c.Length(10000)); m.Property(l => l.ServiceFields, c => c.Length(10000)); }); mapper.Class <AwaitedItem>(i => { i.ManyToOne(l => l.Catalog, c => c.Index("Catalog")); i.ManyToOne(l => l.Producer, c => c.Index("Producer")); }); mapper.Class <Stock>(m => { m.Property(x => x.ServerId, p => p.UniqueKey("ServerIdUniq")); m.Property(x => x.RetailCost, p => p.Access(Accessor.Field)); m.Property(x => x.RetailMarkup, p => p.Access(Accessor.Field)); }); mapper.BeforeMapClass += (inspector, type, customizer) => { customizer.Id(m => m.Generator(Generators.Native)); if (type == typeof(RegulatorRegistry)) { customizer.Table("RegulatorRegistry"); } }; mapper.BeforeMapProperty += (inspector, member, customizer) => { var propertyInfo = ((PropertyInfo)member.LocalMember); var propertyType = propertyInfo.PropertyType; if (member.GetContainerEntity(inspector) == typeof(ProductDescription)) { if (propertyType == typeof(string)) { customizer.Length(10000); } } if (propertyType == typeof(DateTime) || propertyType == typeof(DateTime?)) { customizer.Type <UtcToLocalDateTimeType>(); } if (propertyType.IsValueType && !propertyType.IsNullable()) { customizer.Column(c => c.Default(GetDefaultValue(propertyInfo, mappingDialect))); customizer.NotNullable(true); } if (indexes.Any(m => m.MetadataToken == propertyInfo.MetadataToken && m.Module == propertyInfo.Module)) { customizer.Index(propertyInfo.Name); } }; mapper.BeforeMapManyToMany += (inspector, member, customizer) => { //myisam не поддерживает внешние ключи customizer.ForeignKey("none"); }; mapper.BeforeMapBag += (inspector, member, customizer) => { customizer.Key(k => { k.Column(member.GetContainerEntity(inspector).Name + "Id"); //myisam не поддерживает внешние ключи k.ForeignKey("none"); }); }; mapper.BeforeMapManyToOne += (inspector, member, customizer) => { var propertyInfo = ((PropertyInfo)member.LocalMember); if (propertyInfo.PropertyType == typeof(Price)) { customizer.Columns(cm => cm.Name("PriceId"), cm => cm.Name("RegionId")); } else { customizer.Column(member.LocalMember.Name + "Id"); if (indexes.Contains(propertyInfo)) { customizer.Column(m => m.Index(member.LocalMember.Name + "Id")); } } customizer.NotFound(NotFoundMode.Ignore); //myisam не поддерживает внешние ключи customizer.ForeignKey("none"); }; var assembly = typeof(Offer).Assembly; var types = assembly.GetTypes() .Where(t => t.Namespace != null && t.Namespace.StartsWith("AnalitF.Net.Client.Models")) .Where(t => !t.IsAbstract && !t.IsInterface && t.GetProperty("Id") != null || t == typeof(MinOrderSumRule) || t == typeof(WaybillOrder) || t == typeof(Limit) || t == typeof(Drug)); var mapping = mapper.CompileMappingFor(types); PatchComponentColumnName(mapping); MappingHash = mapping.AsString().GetHashCode(); if (debug) { Console.WriteLine("MappingHash = {0}", MappingHash); Console.WriteLine(mapping.AsString()); } var connectionString = ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString; var driver = "NHibernate.Driver.MySqlDataDriver"; var dialect = typeof(DevartMySqlDialect).AssemblyQualifiedName; if (connectionString.Contains("Embedded=True")) { connectionString = FixRelativePaths(connectionString, database); driver = typeof(DevartDriver).AssemblyQualifiedName; } Configuration = new Configuration(); Configuration.AddProperties(new Dictionary <string, string> { { Environment.Dialect, dialect }, { Environment.ConnectionDriver, driver }, { Environment.ConnectionProvider, "NHibernate.Connection.DriverConnectionProvider" }, { Environment.ConnectionString, connectionString }, { Environment.Hbm2ddlKeyWords, "none" }, #if DEBUG //если нужно отладить запросы хибера //для запросов в AddAwaited падает //{Environment.FormatSql, "true"}, #endif { Environment.ProxyFactoryFactoryClass, typeof(ProxyFactoryFactory).AssemblyQualifiedName }, }); Configuration.SetNamingStrategy(new PluralizeNamingStrategy()); Configuration.AddDeserializedMapping(mapping, assembly.GetName().Name); Factory = Configuration.BuildSessionFactory(); }