2012-02-27 11 views
4

された後に、すべての規則がされた後FluentNHibernateでマッピングされたクラス/コンポーネントに実行時列名を見つけることが可能である場合の取得コラム&テーブル名は、私は疑問に思って適用される。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 

doは次のとおりです。

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

コンポーネント列名が、あなたが望むどのプロパティを知っている必要がありコンポーネントのアプリケーションごとに異なる可能性があるため。

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

うん。それが正しい考えでした。私はあなたに答えを与え、私はあなたの答えの下に 'RuntimeNames'クラスを追加しました。ありがとう! –

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; 
    } 
} 
+0

実際に素晴らしい実装(あなたが設定を知っている場合) – Firo