FluentNHibernate:获得专栏&应用映射约定后的表名称

时间:2012-02-27 05:40:43

标签: fluent-nhibernate fluent-nhibernate-mapping

我想知道在应用所有约定后,是否有可能找到已使用 FluentNHibernate 映射的类/组件的运行时列名。

例如,给出简单的模型:

 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 );
    }
}

表名: tblPerson

  Id     Name     Ssn         ADDRESS_Street     ADDRESS_Zip
 -----------------------------------------------------------
  1      Brian    11223344    123 Example St.    12345

我在寻找什么以及我不知道该怎么做以下内容:

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.

额外澄清

  • 我只对 FluentNHiberante 的约定和映射应用的结果感兴趣。不在NHibernate生成的实际SQL中。

感谢您的帮助,
布赖恩

2 个答案:

答案 0 :(得分:3)

    [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;
    }
}

答案 1 :(得分:2)

由于Component的每个应用程序的组件列名称可能不同,因此您必须知道所需的属性。

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");