2009-03-06 7 views
2

Ich habe die folgende Klasse:Problem Mapping in NHibernate

public class Customer 
{ 
    public virtual int CustomerID { get; protected set; } 
    public virtual string AccountNumber { get; protected set; } 
    public virtual string CustomerType { get; set; } 
    public virtual int TerritoryID { get; set; } 
    public virtual SalesTerritory Territory { get; protected set; } 
} 

Und es mit Fluent NHibernate abgebildet wird, wie folgt:

public class CustomerMapper : ClassMap<Customer> 
{ 
    private const string schema = "Sales"; 
    public CustomerMapper() 
    { 
     SchemaIs(schema); 
     Id(x => x.CustomerID); 
     Map(x => x.CustomerType).WithLengthOf(1).Not.Nullable(); 
     Map(x => x.TerritoryID).Not.Nullable(); 

     Map(x => x.AccountNumber).ReadOnly() 
      .Update(false) 
      .Insert(false) 
      .Generated(Generated.Insert); 

     References<SalesTerritory>(x => x.Territory).TheColumnNameIs(ReflectionHelper.GetProperty<Customer>(x => x.TerritoryID).Name).LazyLoad().Update(false).Insert(false); 
    } 
} 

Die Aktualisierung und Insert Methoden sind nur Erweiterung Methoden, die gesetzt den Update und Attribute einer Eigenschaft Einsatz im erzeugen d Zuordnungsdatei.

Dies ist, wie die resultierende Zuordnungsdatei aussieht:

<?xml version="1.0" encoding="utf-8"?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="true" assembly="Model" namespace="Model" schema="Sales"> 
    <class name="Customer" table="`Customer`" xmlns="urn:nhibernate-mapping-2.2"> 
     <id name="CustomerID" column="CustomerID" type="Int32"> 
      <generator class="identity" /> 
     </id> 
     <property name="AccountNumber" column="AccountNumber" insert="false" update="false" generated="insert" length="100" type="String"> 
      <column name="AccountNumber" /> 
     </property> 
     <property name="TerritoryID" column="TerritoryID" not-null="true" type="Int32"> 
      <column name="TerritoryID" /> 
     </property> 
     <property name="CustomerType" column="CustomerType" not-null="true" length="1" type="String"> 
      <column name="CustomerType" /> 
     </property> 
     <many-to-one lazy="proxy" update="false" insert="false" name="Territory" column="TerritoryID" /> 
    </class> 
</hibernate-mapping> 

Mein Problem ist, dass, wenn ein Kunde eine neue Instanz in der Datenbank speichern, der Kunde Instanz sein Gebiet Eigenschaft als null haben.
Wie kann ich sicherstellen, dass diese Eigenschaft den richtigen Wert nach dem Speichern in der Datenbank enthält? Ich sehe etwas wie das generierte Attribut für Eigenschaften, die den richtigen Wert abrufen, nachdem die Sitzung gelöscht wird.
Oder stimmt etwas mit meiner Kundenklasse nicht?
Vielen Dank im Voraus.

EDIT 1: Die Datenbank, die ich für dieses Modell verwende, ist AdventureWorks (SQL2005), Tabellen Sales.Customer und Sales.SalesTerritory.

Antwort

0

Ich denke, Ihre Zuordnung ist ziemlich seltsam ... Was ist die Beziehung der Eigenschaft territoryId mit der Eigenschaft Territory? In der Viele-zu-Eins-Zuordnung, in der Sie die Eigenschaft Territory zuordnen, müssen Sie nicht den Typ des Gebiets angeben? (Verkaufsterritorium). Sie ordnen 2 Eigenschaften derselben Spalte zu, warum?

+0

Nun, meine Idee war, Modellklassen wie die, die der LINQ to SQL Designer erzeugt, zu erstellen.
Für jeden Verweis auf eine andere Tabelle wird eine Eigenschaft generiert, die die ID enthält, die auf den Primärschlüssel dieser Tabelle verweist, und eine andere Eigenschaft, die die Entität selbst enthält.

+0

Nhibernate funktioniert nicht so. Verwenden Sie einfach Eigenschaften, die auf andere Entitäten zeigen, und NH wird sich um den Rest kümmern. – gcores

2

Eine vernünftige Zuordnung wäre wie:

public class CustomerMapper : ClassMap<Customer> 
{ 
    private const string schema = "Sales"; 
    public CustomerMapper() 
    { 
     SchemaIs(schema); 
     Id(x => x.CustomerID); 
     Map(x => x.CustomerType).WithLengthOf(1).Not.Nullable(); 
     Map(x => x.AccountNumber).ReadOnly() 
      .Generated(Generated.Insert); 
     References(x => x.Territory).LazyLoad(); 
    } 
} 

Einige Punkte:

  • Dies gilt in ein zugeordnetes Salesterritory Klasse.
  • TerritoryID ist nicht erforderlich.
  • Wenn Sie Insert (false) und Update (false) verwenden, werden diese Eigenschaften nicht in der Datenbank gespeichert. ReadOnly() führt sowohl Insert (false) als auch Update (false) durch.
  • CostumerType könnte perfekt ein enum sein.

Dies ist mehr oder weniger die Idee (Luft-Code).

+0

Ich werde mit Ihrem Vorschlag gehen, zunächst tat ich das, scheint der richtige zu sein. Oh, und danke für den Tipp über ReadOnly, wusste dieser +1 nicht. –