2010-11-29 4 views
0

Ich habe eine Entität, die aus Eigenschaften aus zwei verschiedenen Tabellen besteht, wie ich here beschrieben habe und ich Probleme habe, wenn ich ein neues Element einfügen. Beim Einfügen muss ich nur die Felder in einer der beiden Tabellen aktualisieren. Mit der Methode ReadOnly() konnte ich NHibernate veranlassen, die meisten Felder von [RegistrationField] beim Speichern zu ignorieren. Allerdings kann ich nicht versuchen, einen neuen Eintrag für den Fremdschlüssel in [RegistrationField] zu speichern, obwohl für diesen Schlüssel bereits ein Eintrag existiert.Aktualisieren Sie nur eine Tabelle beim Speichern für eine Entität mit mehreren Tabellen

Mein Mapping für die Klasse ist:

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(); 
     }); 
    } 
} 

Wenn ich meinen Test ausführen, um die Abbildung, um zu überprüfen, versucht NHibernate die folgenden zwei SQL-Anweisungen auszuführen:

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)] 

ich nur muß es Führen Sie die erste Anweisung aus, da die Tabelle [RegistrationField] eine statische Liste mit Werten enthält und neue Elemente niemals hinzugefügt werden sollten.

Alle und alle Vorschläge willkommen.

+2

Warten, wenn RegistrationField eine Lookup-Tabelle ist, dann 'Join' ist ** * nicht *** was du brauchst. Die Art und Weise, wie du das Problem beschrieben hast, hat mich dazu gebracht, das zu denken, aber du solltest wahrscheinlich eine regelmäßige Referenz verwenden. –

+0

Ich muss Diego auf diesem einen zustimmen. – Phill

Antwort

0

OK, nachdem ich über Diego's Kommentar nachgedacht und eine gute Nacht geschlafen habe, habe ich den richtigen Weg gefunden, dies zu implementieren und das gewünschte Ergebnis zu erzielen. Diego hat recht, dass ich Reference und nicht Join verwenden sollte. Meine ursprüngliche Argumentation, dies als Join implementieren zu wollen, war der Wunsch, keine weitere Ebene zu meinem Objektgraphen hinzuzufügen. AccountRegistrationField ist bereits eine Eigenschaft auf dem Account Objekt und ich wollte nicht einen Anruf wie Account.AccountRegistrationField.RegistrationField.FieldType machen müssen. Ich wollte stattdessen, dass der Anruf Account.AccountRegistrationField.FieldType ist, da das Objekt, auf dem ich wirklich arbeiten werde, das Objekt AccountRegistrationField ist.

Ich war in der Lage, dieses Verhalten zu bekommen, indem ich meine AccountRegistrationField Klasse etwas besser gestaltete. Ich machte die RegistrationField Eigenschaft privat und fügte öffentliche Eigenschaften auf der AccountRegistrationField Klasse hinzu, um die Felder freizugeben, die ich benötigte. Und dann verwendet Fluent NHibernate Reveal Klasse, um die private Eigenschaft zu meinem Mapping verfügbar zu machen.

Meine AccountRegistrationField Klasse endete diese aussehen wie:

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

Und mein Mapping für AccountRegistrationField wie folgt aussieht:

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

    } 
} 
Verwandte Themen