FLUENTNONBERNATE: ottenere nomi di colonne e tabelle dopo aver applicato le convenzioni di mappatura
-
13-11-2019 - |
Domanda
Mi sto chiedendo se è possibile trovare il nome della colonna Dun-Time per una classe / componente che è stata mappata con fluentnBernate dopo che tutte le convenzioni sono state applicate.
Ad esempio, dato il modello semplice:
.
public class Address{
public string Street {get; set;}
public string Zip {get; set;}
}
public class AddressMap : ComponentMap<Address>{
Map( x => x.Street );
Map( x => x.Zip );
}
public class PersonMap : ClassMap<Person>
{
public PersonMap(){
Id( x => x.Id );
Map( x=> x.Ssn );
Map( x=> x.Name );
Component( x => x.Address )
.ColumnPrefix("ADDRESS_");
}
}
public class ClassConvention : IClassConvention
{
public void Apply( IClassInstance instance )
{
instance.Table( "tbl" + instance.EntityType.Name );
}
}
Nome tabella: tblPerson
.
Id Name Ssn ADDRESS_Street ADDRESS_Zip
-----------------------------------------------------------
1 Brian 11223344 123 Example St. 12345
.
Cosa sto cercando e cosa non sono sicuro di come fare è quanto segue:
.
var mappings = FluentNHibaernate.CompileMergeAndBuildAllMappings();
var zipCodeColumnName = mappings.FindMappedType<Address>().ColumnName(a => a.Zip)
zipCodeColumnName.ShouldBe("ADDRESS_Zip");
// Here I'm interested in the run-time & final column name with the
// prefix applied from the PersonMap class.
var personTableName = mappings.FindMappedType<Person>().TableName;
personTableName.ShouldBe("tblPerson");
// I'm interested in the final table name after the ClassConvention
// modified the table name.
- .
- Sono interessato solo al risultato di fluentnhiberante l'applicazione delle convenzioni e dei mapping.Non nell'intero SQL che viene generato da nibernate.
Grazie per l'aiuto,
Brian
Soluzione
Poiché i nomi delle colonne del componente possono essere diversi per ogni applicazione del componente che devi sapere quale proprietà desiderato.
var config = Fluently.Configure()
.DataBase(...)
.Mappings(...)
.BuildConfiguration();
var map = config.GetClassMapping(typeof(Person));
map.Table.Name.ShouldBe("tblPerson");
map.GetProperty("Address").IsComposite.ShouldBe(true);
((Component)map.GetProperty("Address").Value)
.GetProperty("Zip").ColumnIterator.First()
.Text.ShouldBe("ADDRESS_Zip");
. Altri suggerimenti
[Test]
public void test4()
{
var ssnColumn = RuntimeNames
.ColumnName<Person>( x => x.Ssn );
ssnColumn.ShouldEqual( "Ssn" );
var addressColumn = RuntimeNames
.ColumnName<Person>( x => x.Address.Street );
addressColumn.ShouldEqual( "ADDRESS_Street" );
var personTableName = RuntimeNames
.TableName<Person>();
personTableName.ShouldEqual( "tblPerson" );
}
.
.
public static class RuntimeNames
{
private static Configuration cfg = Fluently.Configure()
.Database( MsSqlConfiguration.MsSql2005 )
.Mappings( m => m.FluentMappings
.AddFromAssemblyOf<PersonMap>()
.Conventions
.AddFromAssemblyOf<PersonMap>()
).BuildConfiguration();
public static string ColumnName<T>( Expression<Func<T, object>> property )
where T : class, new()
{
var accessor = FluentNHibernate.Utils.Reflection
.ReflectionHelper.GetAccessor( property );
var names = accessor.Name.Split('.');
var classMapping = cfg.GetClassMapping( typeof( T ) );
return WalkPropertyChain( classMapping.GetProperty(names.First()), 0, names );
}
private static string WalkPropertyChain(Property property, int index, string[] names)
{
if( property.IsComposite )
return WalkPropertyChain( ((Component)property.Value).GetProperty( names[++index] ), index, names );
return property.ColumnIterator.First().Text;
}
public static string TableName<T>() where T : class, new()
{
return cfg.GetClassMapping( typeof(T) )
.Table.Name;
}
}
.