2011-03-18 244 views
0

我有一个模式,它看起来像这样数据保存到表没有主键

用户

Id INT 
Username VARCHAR(100) 
Password VARCHAR(100) 

User_Info_Key

Id INT 
Description VARCHAR(100) 

USER_INFO

User INT 
Info_Key INT 
Info_Value VARCHAR(100) 
PRIMARY KEY(User, Info_Key) 

这里是我的用户映射文件:

<class name="User" table="[user]"> 
    <id name="Id"> 
    <column name="id" /> 
    <generator class="native" /> 
    </id> 
    <property name="Username" /> 
    <property name="Password" /> 
    <bag name="InfoValues" cascade="all" lazy="false"> 
    <key column="[user]" /> 
    <one-to-many class="FMInfoValue" /> 
    </bag> 
</class> 

<class name="InfoKey" table="[user_info_key]"> 
    <id name="Id"> 
    <column name="id" /> 
    <generator class="native" /> 
    </id> 
    <property name="Description" /> 
</class> 

<class name="InfoValue" table="[user_info]"> 
    <composite-id> 
    <key-property name="User" column="[user]" type="int"></key-property> 
    <key-property name="Key" column="[info_key]" type="int"></key-property> 
    </composite-id> 
    <property name="Value" column="[info_value]" /> 
    <many-to-one name="FMInfoKey" class="FMInfoKey" 
      column="[info_key]" 
      cascade="all" 
      lazy="false" /> 
</class> 

当我创建一个新的用户我这样做:

User newuser = new User(); 
newuser.Username = this.Username; 
newuser.Password = this.Password; 
session.Save(newuser); 

而且这样节省的基本信息。

但是当我尝试添加的第一个名字(信息键值1)和姓(信息键值2)没有被保存到数据库:

InfoValue userfname = new InfoValue(); 
InfoKey userfnamekey = new InfoKey(); 
userfnamekey.Id = 1; 
userfname.InfoKey = userfnamekey; 
userfname.Key = 1; 
userfname.User = (int) newuser.Id; 
userfname.Value = this.Firstname; 
session.Save(userfname); 

InfoValue userlname = new InfoValue(); 
InfoKey userlnamekey = new InfoKey(); 
userlnamekey.Id = 2; 
userlname.InfoKey = userlnamekey; 
userlname.User = (int)newuser.Id; 
userlname.Value = this.Lastname; 
session.Save(userlname); 

如何让NHibernate的保存信息值表中有两个信息值?

+1

如果您发布代码,XML或数据样本,**请**在文本编辑器中突出显示这些行,然后单击编辑器工具栏上的“代码示例”按钮(“{}”)以精确地设置格式和语法突出显示它! – 2011-03-18 23:02:29

回答

2

首先,我想你想要做的是在你的InfoValue类中有两个多对一的属性。这将是这样的:

class InfoValue 
{ 
    public virtual User User { get; set; } 
    public virtual InfoKey Key { get; set; } 
    public virtual String Value { get; set; } 
} 

你的映射会是这个样子:

<class name="InfoValue" table="[user_info]"> 
    <composite-id> 
    <key-many-to-one name="User" column="[user]" lazy="proxy" class="User" /> 
    <key-many-to-one name="Key" column="[info_key]" lazy="proxy" class="InfoKey" /> 
    </composite-id> 
    <property name="Value" column="[info_value]" /> 
</class> 

来自实例在这里拍摄和适应:Composite-id with many-to-one

-----可能不需要的建议 - ----

二,如果我可能如此大胆地提供一些建议,不要这样做。我指的是你的表格结构。如果我的假设是错误的,请随时忽略我的建议。

我假设你想把用户信息放在一个额外的表中,以避免在需要新属性时不得不修改表结构。如果这是原因,我可以诚实地告诉你,从我的经验来看,这会导致很多头痛。查询表格时除了性能问题外,其他所有内容也会更加复杂。你的插入值的例子说明了一切。任何你搜索这些属性的查询都会很糟糕。如果你想保存除Strings之外的任何内容,你会怎么做?投射到int,DateTime,bool等?

我可以继续前进,但除非你以后绝对不能改变表格结构,否则请不要追求这个想法。