2015-01-30 5 views
3

У меня есть вопрос о создании индивидуальной карты в NHIbernate. У меня есть два класса, класса Альбом:NHibernate map one-to-many

public class Album 
{ 
    private int id; 
    private string name; 
    private DateTime releaseDate; 
    private int numberOfTracks; 
    private int totalLength; 
    private int mediaNumber; 

    private Artist artist; 
    private Label label; 
    private Media media; 

    private int reservationId = -1; 
    private IList<Reservation> reservations = new List<Reservation>(); 
    private int sold; 
    private int aviable; 


    public int Id 
    { 
     get { return id; } 
     set { id = value; } 
    } 

    public string Name 
    { 
     get { return name; } 
     set { name = value; } 
    } 

    public DateTime ReleaseDate 
    { 
     get { return releaseDate; } 
     set { releaseDate = value; } 
    } 

    public int NumberOfTracks 
    { 
     get { return numberOfTracks; } 
     set { numberOfTracks = value; } 
    } 

    public int TotalLength 
    { 
     get { return totalLength; } 
     set { totalLength = value; } 
    } 

    public int MediaNumber 
    { 
     get { return mediaNumber; } 
     set { mediaNumber = value; } 
    } 

    public Artist Artist 
    { 
     get { return artist; } 
     set { artist = value; } 
    } 

    public Label Label 
    { 
     get { return label; } 
     set { label = value; } 
    } 

    public Media Media 
    { 
     get { return media; } 
     set { media = value; } 
    } 

    public int Aviable 
    { 
     get { return aviable; } 
     set { aviable = value; } 

    } 

    public int Sold 
    { 
     get { return sold; } 
     set { sold = value; } 
    } 

    public string Lookup 
    { 
     get { return artist.Name + " - " + Name+ " ("+releaseDate.Year+")"; } 
    } 

    public int ReservationId 
    { 
     get { return reservationId; } 
     set { reservationId = value; } 
    } 
    public IList<Reservation> Reservations 
    { 
     get { return reservations; } 
     set { reservations = value; } 
    } 

    public int GenerateCode() 
    { 
     Random rnd = new Random();   
     return rnd.Next(1000, 10000); 
    } 

    public Album() 
    { 

    } 

    public Album(string inName, DateTime inReleaseDate, int inNumberOfTracks, int inTotalLength, int inMediaNumber, int inAviable, Artist inArtist, Label inLabel, Media inMedia) 
    { 
     Name = inName; 
     ReleaseDate = inReleaseDate; 
     NumberOfTracks = inNumberOfTracks; 
     TotalLength = inTotalLength; 
     MediaNumber = inMediaNumber; 
     Artist = inArtist; 
     Label = inLabel; 
     Media = inMedia; 
     Aviable = inAviable; 
     Sold = 0; 

    } 

    public void AddReservation(string numberOfAlbums) 
    { 
     if (string.IsNullOrEmpty(numberOfAlbums) || !Regex.IsMatch(numberOfAlbums, @"^[0-9]")) 
     { 
      throw new InvalidReservationFormatException(); 
     } 

     if (Convert.ToInt32(numberOfAlbums) > Aviable) 
     { 
      throw new InvalidReservationSizeException(); 
     } 

     reservationId += 1; 
     Reservation reservation = new Reservation(reservationId,GenerateCode(), Convert.ToInt32(numberOfAlbums)); 

     reservations.Add(reservation); 
     Aviable -= Convert.ToInt32(numberOfAlbums); 
    } 

    public void PickUpReservation(string reservationCode) 
    { 
     if (Reservations.Count == 0) 
     { 
      throw new InvalidZeroReservationsException(); 
     } 

     if (string.IsNullOrEmpty(reservationCode) || !Regex.IsMatch(reservationCode, @"^[0-9]") || Convert.ToInt32(reservationCode) > 9999 || Convert.ToInt32(reservationCode) < 1000) 
     { 
      throw new InvalidReservationCodeFormatException(); 
     } 

     for (int i = 0; i < reservations.Count; i++) 
     { 
      if (reservations[i].ReservationCode == Convert.ToInt32(reservationCode)) 
      { 
       Console.WriteLine(reservations[i].ReservationCode); 
       Sold += reservations[i].NumberOfAlbums; 
       reservations.RemoveAt(i); 
       return; 
      } 
     } 

     throw new InvalidReservationCodeException(); 
    } 

    public void DropReservation(string reservationCode) 
    { 
     if (Reservations.Count == 0) 
     { 
      throw new InvalidZeroReservationsException(); 
     } 

     if (string.IsNullOrEmpty(reservationCode) || !Regex.IsMatch(reservationCode, @"^[0-9]") || Convert.ToInt32(reservationCode) > 9999 || Convert.ToInt32(reservationCode) < 1000) 
     { 
      throw new InvalidReservationCodeFormatException(); 
     } 

     for (int i = 0; i < reservations.Count; i++) 
     { 
      if (reservations[i].ReservationCode == Convert.ToInt32(reservationCode)) 
      { 
       Aviable += reservations[i].NumberOfAlbums; 
       reservations.RemoveAt(i); 
       return; 
      } 
     } 

     throw new InvalidReservationCodeException(); 
    } 

    public void SellAlbum(string numberOfAlbums) 
    { 
     if (string.IsNullOrEmpty(numberOfAlbums) || !Regex.IsMatch(numberOfAlbums, @"^[0-9]")) 
     { 
      throw new InvalidReservationFormatException(); 
     } 

     if (Convert.ToInt32(numberOfAlbums) > Aviable) 
     { 
      throw new InvalidReservationSizeException(); 
     } 

     Aviable -= Convert.ToInt32(numberOfAlbums); 
     Sold += Convert.ToInt32(numberOfAlbums); 
    } 

    public double GetIncome() 
    { 
     return this.Media.PricePerTrack(numberOfTracks)*Sold; 
    } 

    public bool HasArtist(int id) 
    { 
     return Artist.Id == id; 
    } 

    public bool HasLabel(int id) 
    { 
     return Label.Id == id; 
    } 

    public bool HasMedia(int id) 
    { 
     return Media.Id == id; 
    } 

} 

и бронирование Класс:

public class Reservation 
{ 
    private int id; 
    private int numberOfAlbums; 
    private int reservationCode; 
    private int reservationId; 

    public int ReservationId 
    { 
     get { return reservationId; } 
     set { reservationId = value; } 
    } 
    public int NumberOfAlbums 
    { 
     get { return numberOfAlbums; } 
     set { numberOfAlbums = value; } 
    } 

    public int ReservationCode 
    { 
     get { return reservationCode; } 
     set { reservationCode = value; } 
    } 

    public int Id 
    { 
     get { return id; } 
     set { id = value; } 
    } 

    public Reservation() 
    { 

    } 
    public Reservation(int inId, int inReservationCode, int inNumberOfAlbums) 
    { 
     NumberOfAlbums = inNumberOfAlbums; 
     ReservationCode = inReservationCode; 
     Id = inId; 
    } 


} 

Так что я хочу, чтобы сопоставить эти 2 класса. Вот мои XMLs:

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="FromCDToVinyl.DomainModel" namespace="FromCDToVinyl.DomainModel"> 
    <class name="FromCDToVinyl.DomainModel.Album, FromCDToVinyl.DomainModel" table="Album" lazy="false" discriminator-value="Album"> 
    <id name="Id" column="Id"> 
     <generator class="native"/> 
    </id> 
    <property name="Name" column="Name"/> 
    <property name="ReleaseDate" column="ReleaseDate"/> 
    <property name="NumberOfTracks" column="NumberOfTracks"/> 
    <property name="TotalLength" column="TotalLength"/> 
    <property name="MediaNumber" column="MediaNumber"/> 
    <property name="Aviable" column="Aviable"/> 
    <property name="Sold" column="Sold"/> 
    <property name="ReservationId" column="ReservationId"/> 
    <many-to-one name="Artist" class="FromCDToVinyl.DomainModel.Artist, FromCDToVinyl.DomainModel" column="Artist"/> 
    <many-to-one name="Label" class="FromCDToVinyl.DomainModel.Label, FromCDToVinyl.DomainModel" column="Label"/> 
    <many-to-one name="Media" class="FromCDToVinyl.DomainModel.Media, FromCDToVinyl.DomainModel" column="Media"/> 
    <list name="Reservations" table="Reservation" cascade="all-delete-orphan"> 
     <key column="Id"/> 
     <index column="Position"/> 
     <one-to-many class="FromCDToVinyl.DomainModel.Reservation, FromCDToVinyl.DomainModel"/> 
    </list> 
    </class> 
</hibernate-mapping> 

    <?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="FromCDToVinyl.DomainModel" namespace="FromCDToVinyl.DomainModel"> 
    <class name="FromCDToVinyl.DomainModel.Reservation, FromCDToVinyl.DomainModel" table="Reservation" lazy="false" discriminator-value="Reservation"> 
    <id name="ReservationId" column="ReservationId"> 
     <generator class="native"/> 
    </id> 
    <property name="Id" column="Id"/> 
    <property name="ReservationCode" column="ReservationCode"/> 
    <property name="NumberOfAlbums" column="NumberOfAlbums"/> 
    </class> 
</hibernate-mapping> 

Проблема в том, каждый раз, когда я пытаюсь добавить новую оговорку в альбом я получаю сообщение об ошибке:

An unhandled exception of type 'NHibernate.Exceptions.GenericADOException' occurred in NHibernate.dll 

Additional information: could not insert: [FromCDToVinyl.DomainModel.Reservation][SQL: INSERT INTO Reservation (Id, ReservationCode, NumberOfAlbums) VALUES (?, ?, ?); select last_insert_rowid()] 

Любой человек может помочь?

+1

это ваша проблема: '<имя = Идентификатор столбца "Идентификатор" = "Id"> 'он терпит неудачу, когда он пытается получить pri mery key из новой строки –

+0

Так что же такое решение? – TranceFusion

+0

Сделали ли вы свои первичные ключи автоматическим приращением? – Andre

ответ

1

Yup проблема была в линии, предложенной AK_ (спасибо за это). Единственное, что я изменил был

`<id name="Id" column="Id"> <generator class="native"/>` 

в

`<id name="Id" column="AlbumId"> <generator class="native"/>` 

и

<list name="Reservations" table="Reservation" cascade="all-delete-orphan"> 
     <key column="Id"/> 
     <index column="Position"/> 
     <one-to-many class="FromCDToVinyl.DomainModel.Reservation, FromCDToVinyl.DomainModel"/> 
</list> 

в

<list name="Reservations" table="Reservation" cascade="all-delete-orphan"> 
     <key column="AlbumId"/> 
     <index column="Position"/> 
     <one-to-many class="FromCDToVinyl.DomainModel.Reservation, FromCDToVinyl.DomainModel"/> 
</list> 
Смежные вопросы