2009-09-01 31 views
5

我想弄清楚如何在Fluent 1.0 RTM中映射IDictionary屬性。用於映射IDictionary的流利代碼<SomeEntity,int>?

根據我的理解,這轉換爲三元關聯。

例如:然後

class Bar 
{ 
    public IDictionary<SomeEntity, int> Foo {get; set;} 
} 

Bar.hbm.xml將包含:

<map name="Foo" table="BarFooTable"> 
    <key column="..."/> 
    <index-many-to-many class="SomeEntity" column="SomeEntity_Id"/> 
    <element column="Value" type="int"/> 
</map> 

我會在什麼連貫NHibernate產生這種映射XML寫?

這裏感興趣的一點是,鍵是一個實體類型,而值是一個值類型。 (編輯:至少,這似乎區別於各種其他的例子和問題浮動在計算器或谷歌組,這是價值或鍵 - 鍵)

經過大量的實驗後,我可以產生一個映射IDictionary<SomeEntity,SomeEntity>(純實體類型):

HasManyToMany(x => x.Foo) 
     .AsMap("Key") 
     .AsTernaryAssociation("Key2", "Value") 
     ; 

我還可以產生用於IDictionary<int,int>(純值類型)的映射:

HasMany(x => x.Foo) 
    .AsMap<int>("Key") 
    .Element("Value") 
    ; 

我甚至可以得到某種方式製造用於的映射,儘管NHibernate不會接受。

但我不知道如何產生IDictionary<SomeValue, int>這是我想要的映射。有人可以提供一些提示嗎?

+0

crossposted到http://groups.google.com/group/fluent-nhibernate/browse_thread/thread/b1b335ff5f9a6a40 – fostandy 2009-09-05 16:18:38

回答

1

我碰到了同樣的問題,WASN」不喜歡混合流利和HBM映射。你可以看到我的修復here

0

看來,我們有同樣的問題:

How to map this in Fluent.NHibernate

我只是用的hbm.xml(即由Fluent.Nhibernate在我的項目產生的)我修改了一些oufcourse。 如果設置

.Mappings(m => 
    {            
     m.FluentMappings.AddFromAssemblyOf<DomainClass>() 
         .ExportTo("Path"); 
     m.HbmMappings.AddFromAssemblyOf<DomainClass>(); 
    }) 

,如果你有兩個類映射和的hbm.xml你hml.xml應該重寫類映射,所以你會沒事的,直到它的固定。

我還需要自然-ID爲我的類,它也沒有與Fluent.Nhibernate支持,所以我只好用的hbm.xml

+0

啊,這是目前我的方式做事情也是如此。不幸的是,我有一個相當重的類,雖然它有很多可以用流暢映射的屬性,但也有一個IDictionary 。我的'解決方案'就是將功能分成單獨的類(一個流暢地映射,一個通過原始hbm.xml映射)並使用一對一映射,但出於性能方面的原因,現在需要消除加入/額外選擇由此發生。 (請參閱http://groups.google.com/group/fluent-nhibernate/browse_frm/thread/b5fe376e257436e9/35d9cf5cef4303d0) – fostandy 2009-09-05 16:25:00

2
HasMany(x => x.Foo) 
    .KeyColumn("BarId") 
    .Element("IntValue") 
    .AsMap<SomeEntity>("SomeEntityId") 
    .AsTernaryAssociation("SomeEntityId"); 
+0

剛剛有同樣的問題,根據您的解決方案,我最終與 'HasManyToMany(x => x。集合) \t \t \t \t .ParentKeyColumn( 「的ParentId」) \t \t \t \t .ChildKeyColumn( 「childID的」) \t \t \t \t .AsMap ( 「childID的」)。元素( 「值」,p值=>點。列(「值」)。類型()) \t \t \t \t .AsTernaryAssociation( 「childID的」, 「值」) \t \t \t \t \t \t \t \t。表( 「Relationstable」);' – 2011-04-04 14:27:23

0

鑑於這些(簡體)類:

class LetterTemplate 
{ 
    IDictionary<State, FieldAccessOptionality> StateAccess {get; protected set;} 
} 

class State 
{ 
} 

enum FieldAccessOptionality 
{ 
} 

這爲我工作。

(是的,我知道這個值是一個枚舉,但其原理與int相同)。

HasManyToMany(x => x.StateAccess) 
    .ParentKeyColumn("`letter_template`") 
    .ChildKeyColumn("`state`") 
    .AsMap<State>("`state`") 
    .Element("`access`", 
     p => 
     p.Type<IntEnumType<FieldAccessOptionality>>()) 
    .AsTernaryAssociation("`state`", "`access`") 
    .Table("`letter_template_state_access`"); 

注意IntEnumType <>類,從枚舉轉換爲用於NHibernate的一個int。 如果你映射一個int而不是一個枚舉,你可以使用標準的NHibernate Int32Type IUserType。 這個類的完整清單如下:

public class IntEnumType<T> : IUserType where T : struct 
{ 
    public object Assemble(object cached, object owner) 
    { 
    return cached; 
    } 

    public object DeepCopy(object value) 
    { 
    return value; 
    } 

    public object Disassemble(object value) 
    { 
    return value; 
    } 

    public new bool Equals(object a, object b) 
    { 
    return Object.Equals(a, b); 
    } 

    public int GetHashCode(object x) 
    { 
    if (x == null) 
     return 0; 
    else 
     return x.GetHashCode(); 
    } 

    public bool IsMutable 
    { 
    get { return false; } 
    } 

    public object NullSafeGet(IDataReader rs, string[] names, object owner) 
    { 
    object result = NHibernateUtil.Int32.NullSafeGet(rs, names); 
    if (result == null) 
    { 
     return null; 
    } 
    else 
    { 
     Type typ = Enum.GetUnderlyingType(typeof(T)); 
     result = Convert.ChangeType(result, typ); 
     return Enum.ToObject(typeof(T), result); 
    } 
    } 

    public void NullSafeSet(IDbCommand cmd, object value, int index) 
    { 
    if (value == null) 
     ((IDataParameter)cmd.Parameters[index]).Value = DBNull.Value; 
    else 
     ((IDataParameter)cmd.Parameters[index]).Value = Convert.ChangeType(value, typeof(int)); 
    } 

    public object Replace(object original, object target, object owner) 
    { 
    return original; 
    } 

    public Type ReturnedType 
    { 
    get { return typeof(T); } 
    } 

    public SqlType[] SqlTypes 
    { 
    get 
    { 
     SqlType type = new SqlType(DbType.Int32); 
     return new SqlType[] { type }; 
    } 
    } 

}