2009-03-06 3 views
2

Я следующий класс:Проблема с отображением в 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; } 
} 

И он привязывается с помощью Fluent NHibernate следующим образом:

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

обновление и Вставить методы только методы расширения, которые установить обновление и Вставить атрибуты свойства в генерации d файл сопоставления.

Это, как выглядит результирующий файл отображения:

<?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> 

Моя проблема заключается в том, что при сохранении нового экземпляра клиента в базу данных, экземпляр клиент имеет свою собственность территорию как нуль.
Как я могу заставить это свойство содержать правильное значение после сохранения в базе данных? Я смотрю на что-то вроде сгенерированный атрибут для свойств, которые извлекают правильное значение после очистки сеанса.
Или что-то не так с моим классом Customer?
Заранее спасибо.

EDIT 1: База данных, которую я использую для этой модели, - AdventureWorks (SQL2005), таблицы Sales.Customer и Sales.SalesTerritory.

ответ

0

Я думаю, что ваше картографирование довольно странно ... Каково отношение территории собственности с территорией собственности? В сопоставлении «много-к-одному», где вы указываете свойство Territory, вам не нужно указывать тип территории? (SalesTerritory). Вы сопоставляете 2 свойства с тем же столбцом, почему?

+0

Ну, моя идея заключалась в создании классов моделей, подобных тем, которые генерирует конструктор LINQ to SQL.
Для каждой ссылки на другую таблицу создается свойство, которое содержит идентификатор, указывающий на ключ primery этой таблицы и другое свойство, которое содержит сам объект.

+0

Nhibernate не работает. Просто используйте свойства, указывающие на другие объекты, и NH позаботится о вас для остальных. – gcores

2

Более разумное отображение будет, как:

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

некоторых точек:

  • Это считается в том, отображенный SalesTerritory класс.
  • ТерриторияID не требуется.
  • Если вы используете Insert (false) и Update (false), эти свойства не будут сохранены в базе данных. ReadOnly() выполняет как Insert (false), так и Update (false).
  • CostumerType вполне может быть перечислением.

Это более или менее идея (воздушный код).

+0

Я собираюсь пойти с вашим предложением, изначально я делал это, кажется, правильным. О, и спасибо за отзыв о ReadOnly, не знал об этом +1. –