2010-11-29 51 views
0

我有一个实体由两个不同表的属性组成,如我所描述的here,当我尝试插入新项目时遇到问题。插入时,我只需要更新两个表格之一中的字段。使用ReadOnly()方法,我已经能够让NHibernate在保存时忽略来自[RegistrationField]的大部分字段。然而,即使该密钥的条目已经存在,我也无法使它不尝试为外键保存[RegistrationField]的新条目。只更新一个表保存多表实体

我为类的映射是:

public class RegistrationFieldMap : ClassMap<RegistrationField> 
{ 
    public RegistrationFieldMap() 
    { 
     Table("AccountRegistrationField"); 

     Id(r => r.ID).Column("RegistrationID"); 
     Map(r => r.AccountID); 
     Map(r => r.DefaultValue); 
     Map(r => r.FieldID); 
     Map(r => r.IsRequired); 
     Map(r => r.Label); 
     Map(r => r.Priority); 
     Join("RegistrationField", t => 
     { 
      t.Map(r => r.FieldType).ReadOnly(); 
      t.Map(r => r.HtmlID).ReadOnly(); 
     }); 
    } 
} 

当我运行我的测试,以验证映射,NHibernate的尝试运行以下两个SQL语句:

INSERT INTO AccountRegistrationField (
    AccountID, 
    DefaultValue, 
    FieldID, 
    IsRequired, 
    Label, 
    Priority) 
VALUES (@p0, @p1, @p2, @p3, @p4, @p5); 
select SCOPE_IDENTITY(); 
@p0 = 1 [Type: Int32 (0)], 
@p1 = 'bar' [Type: String (4000)], 
@p2 = 1 [Type: Int32 (0)], 
@p3 = False [Type: Boolean (0)], 
@p4 = 'bar' [Type: String (4000)], 
@p5 = 1 [Type: Int32 (0)] 

INSERT INTO RegistrationField (UserRegistrationField_id) VALUES (@p0); 
@p0 = 12 [Type: Int32 (0)] 

我只需要它运行第一条语句,因为[RegistrationField]表包含一个静态值列表,并且永远不应该添加新项目。

欢迎任何和所有建议。

+2

等待,如果RegistrationField是一个查找表,然后`Join`是** *不***你需要什么。你描述问题的方式让我觉得这样,但你应该使用一个常规的参考 – 2010-11-29 20:19:26

回答

0

好吧,在考虑了迭戈的评论并获得了良好的夜间睡眠后,我想出了实现这一点并获得我想要的结果的正确方法。迭戈是对的,我应该使用Reference而不是Join。我最初想要将它作为连接实现的原因是希望避免在对象图中添加另一个层次。 AccountRegistrationField已经是Account对象的属性,我不想拨打电话Account.AccountRegistrationField.RegistrationField.FieldType。我反而希望电话是Account.AccountRegistrationField.FieldType,因为我真正要操作的对象是AccountRegistrationField对象。

我能够通过设计我的AccountRegistrationField类更好一点来获得此行为。我将RegistrationField属性设置为private,并在AccountRegistrationField类上添加公共属性以公开我需要的字段。然后使用Fluent NHibernate的Reveal类将私有属性公开给我的映射。

AccountRegistrationField下课这样看:

public class AccountRegistrationField 
{ 
    public virtual int ID { get; set; } 
    public virtual int AccountID { get; set; } 
    public virtual string DefaultValue { get; set; } 
    public virtual int FieldID { get; set; } 
    public virtual string HtmlID 
    { 
     get { return RegistrationField.HtmlID; } 
    } 
    public virtual bool IsRequired { get; set; } 
    public virtual string Label { get; set; } 
    public virtual int Priority { get; set; } 
    public virtual string FieldType 
    { 
     get { return RegistrationField.FieldType; } 
    } 

    private RegistrationField RegistrationField { get; set; } 
} 

而且我对AccountRegistrationField映射的样子:

public class AccountRegistrationFieldMap : ClassMap<AccountRegistrationField> 
{ 
    public AccountRegistrationFieldMap() 
    { 
     Table("AccountRegistrationField"); 

     Id(r => r.ID).Column("RegistrationID"); 
     Map(r => r.AccountID); 
     Map(r => r.DefaultValue); 
     Map(r => r.IsRequired); 
     Map(r => r.Label); 
     Map(r => r.Priority); 
     References<RegistrationField>(
       Reveal.Member<AccountRegistrationField>("RegistrationField")) 
      .Column("FieldID"); 

    } 
}