/// <summary> /// Maps the defined <see cref="Type"/> to the supplied <see cref="TypeMap"/> using /// attributes from the <see cref="N:Ikarii.Lib.Data.Alpaca.Attributes"/> namespace. /// </summary> /// <param name="t"><see cref="Type"/> to map.</param> /// <param name="otm"><see cref="TypeMap"/> instance to populate with mappings.</param> public override void MapByType( Type t, TypeMap otm ) { this.Context = otm; this.Context.Table = this.GetTableName( t ); this.Context.SetNamingConvention( this.GetConvention( t ) ); List<PropertyInfo> fields = new List<PropertyInfo>( t.GetProperties() ); fields.FindAll( f => ValidField( f, t ) ) .ForEach( f => this.HandleField( f, Utility.GetCustomFieldAttribute<IFieldAttribute>( f ), t ) ); }
/// <summary> /// Maps the given <see cref="T:Type"/> <paramref name="t"/> to the specified <see cref="T:TypeMap"/> <paramref name="otm"/>. /// </summary> /// <param name="t"><see cref="T:Type"/> to map.</param> /// <param name="otm"><see cref="T:TypeMap"/> to populate.</param> public override void MapByType( Type t, TypeMap otm ) { this.Context = otm; this.Context.SetNamingConvention( Configuration.AlpacaConfiguration.Settings.GetNamingConvention() ); List<PropertyInfo> fields = new List<PropertyInfo>( t.GetProperties() ); this.Context.SetPrimaryKey( FindPrimaryKey( fields ) ); this.FindChildren( fields ); this.FindForeignKeys( fields ); this.FindReferencedFields( fields ); fields.FindAll( f => Utility.IsElemental( f.PropertyType ) ) .ForEach( value => this.HandleField( value ) ); }
/// <summary> /// Instantiates PersistentPackage to be used for persistence operations. /// <remarks>This is useful when you have a sub class instantiated and want to deserialize or serialize it's base.</remarks> /// </summary> /// <param name="o"><see cref="T:Object"/> marked with <see cref="T:Ikarii.Lib.Data.Alpaca.PersistentAttribute"/>.</param> /// <param name="t"><see cref="T:Type"/> marked with <see cref="T:Ikarii.Lib.Data.Alpaca.PersistentAttribute"/>.</param> /// <param name="parent">Parent <see cref="T:ObjectTypeMap"/> which will be used in operations where the ForeignKey of this object is needed.</param> /// <param name="mappingProvider">The <see cref="T:IMappingProvider"/> used to create the <see cref="T:PersistentObject"/>.</param> internal ObjectPackage( object o, Type t, TypeMap parent, IMappingProvider mappingProvider ) { this.MappingProvider = mappingProvider; this.ParentMap = parent; this.Instance = o; if ( TypeCache.ContainsType( t ) ) { this.Map = TypeCache.GetType( t ); } else { this.Map = new TypeMap( t, mappingProvider ); TypeCache.AddType( t, this.Map ); } }
private void FindChildren( List<PropertyInfo> fields ) { fields.FindAll( f => this.CanMapByType( f.PropertyType ) && f.CanWrite ) .ForEach( child => { TypeMap childmap = new TypeMap( child.PropertyType, new ActiveMappingProvider() ); List<FieldMap> fks = childmap.ForeignKeys.ToList(); FieldMap fm = fks.Find( parent => parent.FieldReturnType.Equals( this.Context.Type ) ); this.Context.AddChild( new PersistentFieldMap() { Field = child, ChildReturnType = child.PropertyType, Behavior = FieldBehavior.Inherit, Cascade = Cascade.All, Linked = false, Lazy = false } ); } ); //Children that are contained in collections MUST be named plural of their type. //So if a Car has more than one Tire in a ICollection, the Collection must be named Tires fields.FindAll( f => Utility.ImplementsInterface( f.PropertyType, typeof( ICollection ) ) ) .ForEach( child => { Type innerChild = Type.GetType( String.Format( "{0}.{1}", child.PropertyType.Namespace, Helper.Inflector.Singularize( child.Name ) ) ); TypeMap childmap = new TypeMap( innerChild, new ActiveMappingProvider() ); List<FieldMap> fks = childmap.ForeignKeys.ToList(); FieldMap fm = fks.Find( parent => parent.FieldReturnType.Equals( this.Context.Type ) ); this.Context.AddChild( new PersistentFieldMap() { Field = child, ChildReturnType = child.PropertyType, Behavior = FieldBehavior.Inherit, Cascade = ( fm.Null() ? Cascade.Update : Cascade.All ), Linked = ( fm.Null() ? true : false ), Lazy = false } ); } ); }
/// <summary> /// Maps the defined <see cref="T:Type"/> to the supplied <see cref="T:TypeMap"/>. /// </summary> /// <param name="t"><see cref="T:Type"/> to map.</param> /// <param name="otm"><see cref="T:TypeMap"/> instance to populate with mappings.</param> public abstract void MapByType( Type t, TypeMap otm );
/// <summary> /// Instantiates PersistentPackage to be used for persistence operations. /// </summary> /// <param name="t"><see cref="Type"/> marked with <see cref="Ikarii.Lib.Data.Alpaca.Meta.PersistentAttribute"/>.</param> /// <param name="parent">Parent <see cref="PersistentObject"/> which will be used in operations where the ForeignKey of this object is needed.</param> /// <param name="mappingProvider">The <see cref="IMappingProvider"/> used to create the <see cref="PersistentObject"/>.</param> internal ObjectPackage( Type t, TypeMap parent, IMappingProvider mappingProvider ) : this(t.Assembly.CreateInstance( t.FullName ), t, parent, mappingProvider) { }
/// <summary> /// Registers a <see cref="T:TypeMap"/> with the Type cache. /// </summary> /// <param name="typemap"><see cref="T:TypeMap"/> to register.</param> public void RegisterTypeMap( TypeMap typemap ) { TypeCache.AddType( typemap.Type, typemap ); }
private void FindReferencedFields( List<PropertyInfo> fields ) { //if field is object and can be mapped and does not have a reference to this object via identity or type fields.FindAll( f => this.CanMapByType( f.PropertyType ) && f.CanWrite ) .ForEach( child => { TypeMap childmap = new TypeMap( child.PropertyType, new ActiveMappingProvider() ); List<FieldMap> fks = childmap.ForeignKeys.ToList(); FieldMap fm = fks.Find( parent => parent.FieldReturnType.Equals( this.Context.Type ) ); if ( fm.Null() ) { this.Context.AddReferencedField( new FieldMap() { Field = child, Behavior = FieldBehavior.Inherit, Cascade = Cascade.None, MappingType = FieldMappingType.Reference } ); } } ); }