FLUENTNONBERNATE: ottenere nomi di colonne e tabelle dopo aver applicato le convenzioni di mappatura

StackOverflow https://stackoverflow.com/questions/9460522

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.
.

chiarimento aggiuntivo

    .
  • 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

È stato utile?

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;
    }
}
.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top