2011-08-19 90 views
4

TL; DR:我試圖在多對多表上添加多列多列表Order列。 HBM效果很好。無法獲得FluentNHibernate映射的工作。將HBM映射到FluentNHibernate的多對多映射時遇到困難

我有以下兩類其中我試圖用許多一對多的關係映射:

public class User 
{ 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
    private IDictionary<int, Profile> profilesMap; 

    public virtual IEnumerable<Profile> Profiles { get { return this.profilesMap.Select(kvp => kvp.Value); } } 

    public User() 
    { 
     this.profilesMap = new SortedDictionary<int, Profile>(); 
    } 

    public virtual void Add(Profile x) 
    { 
     profilesMap.Add(x); 
    } 
} 

public class Profile 
{ 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
} 

profilesMap的關鍵是輪廓順序。因此,HBM映射如下:

<class name="User" table="User"> 
    <id name="Id" column="Id" type="integer"> 
    <generator class="native" /> 
    </id> 
    <property name="Name" type="string" column="Name" /> 
    <map name="profilesMap" access="field.camelcase" table="User_Profile"> 
    <key column="User_Id" /> 
    <index column="`Order`" type="integer" /> 
    <many-to-many class="Profile" column="Profile_Id" /> 
    </map> 
</class> 
<class name="Profile" table="Profile"> 
    <id name="Id" column="Id" type="integer"> 
    <generator class="native" /> 
    </id> 
    <property name="Name" type="string" column="Name" /> 
</class> 

這完美的作品,並創建正確的許多一對多表:

create table User_Profile (
    User_Id INT not null, 
    Profile_Id INT not null, 
    "Order" INT not null, 
    primary key (User_Id, "Order"), 
    constraint FK6BDEDC07D1EDE651 foreign key (Profile_Id) references Profile, 
    constraint FK6BDEDC07650CB01 foreign key (User_Id) references User 
) 

不過,我並不特別喜歡使用因爲HBM這不是真的重構友好。因此,我試圖將其轉換爲FluentNHibernate。這是我在嘗試的用戶的許多一對多映射:

public class UserMap : ClassMap<User> 
{ 
    public UserMap() 
    { 
     this.Id(); 
     this.Map(o => o.Name); 

     var mapMember = Reveal.Member<User, IEnumerable<KeyValuePair<int, Profile>>>("profilesMap"); 

     this.HasManyToMany<KeyValuePair<int, Profile>>(mapMember) 
      .Access.CamelCaseField() 
      .AsMap<int>("`Order`") 
      .Table("User_Profile"); 
    } 
} 

我預計這個工作,但它試圖建立會話工廠時炸燬:

從表中的關聯User_Profile引用了一個未映射的類:System.Collections.Generic.KeyValuePair`2 [[System.Int32,mscorlib,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089],[ConsoleApplication9.Profile,ConsoleApplication9,Version = 1.0。 0.0,文化=中立,PublicKeyToken = null]]

我如何獲得AsMap相當多的研究工作,所以我把它改成如下:

this.HasManyToMany<KeyValuePair<int, Profile>>(mapMember) 
    .Access.CamelCaseField().AsMap<int>("`Order`") 
    .Element("Profile_id", ep => ep.Type<int>()) // Added. 
    .Table("User_Profile"); 

然而,這種由包括外鍵產生不正確的表(或NOT NULL約束)從Profile_id

0123:

create table User_Profile (
    User_id INT not null, 
    Profile_id INT, 
    "Order" INT not null, 
    primary key (User_id, "Order"), 
    constraint FK6BDEDC07650CB01 foreign key (User_id) references "User") 

此外,它也試圖將配置文件添加到用戶時炸燬

所以 - 我一直拉着我的頭髮幾個小時試圖確定如何正確地映射這種關係與FNH,但我似乎無法得到它。簡單的多對多關係看起來很容易,但是當試圖添加索引列時,它似乎不起作用。如果有人願意幫我解決這個問題,我將不勝感激。

回答

2

您是否看到過類似問題的答案?

How to map IDictionary<string, Entity> in Fluent NHibernate

一個問題,我看到的是在你的多對多使用的元素。這可能是爲什麼你沒有爲profile_id獲取任何外鍵設置。另外,如果可能的話,我會嘗試爲profilesMap添加公共訪問器。

要匹配你的情況,我會想辦法讓你的映射如下:

HasManyToMany<Profile>(ProfilesMap) //Assuming the addition of a public get accessor 
    .Access.CamelCaseField() 
    .ParentKeyColumn("User_Id") 
    .ChildKeyColumn("Profile_Id") 
    .Table("User_Profile") 
    .AsMap<int>("Id"); 

如果您不能添加訪問你可以試試這個

HasManyToMany<Profile>(Reveal.Member<User, object>("profilesMap")) 
    .Table("User_Profile") 
    .ParentKeyColumn("User_id") 
    .ChildKeyColumn("Profile_id") 
    .AsMap<int>("`Order`"); 
+0

完美!將第二個參數'Reveal.Member'作爲'object' *真的做了一個清除事情的技巧(以及父/子鍵列)。我欠你的不僅僅是一個投票!乾杯! – TheCloudlessSky

+0

另外 - 我希望你不介意,但我編輯你的答案,直接映射到OP的解決方案。再次感謝! – TheCloudlessSky