2016-04-20 155 views
0

我一整天都在試圖找出我應該如何處理這個問題。問題是,當我使用EF向數據庫添加「Reservation」實體時,它會向我不需要的表中添加一些不必要的內容。我不確定它的數據模型是否會導致問題。實體框架:添加實體到數據庫跳過添加到特定表

已經創建了一個看起來像這樣的數據模型:

enter image description here

有一個許多人預約,房間之間有很多關係。許多預訂只能容納1個聯繫人。

我的模式是這樣的:

預訂:(已經離開了不需要的屬性)

public class Reservation 
{ 
    public int ReservationID { get; set; } 
    public int ContactPersonID { get; set; } 

    public virtual ContactPerson ContactPerson { get; set; } 
    public virtual ICollection<Room> Room { get; set; } 

    public Reservation() 
    { 
     Room = new List<Room>(); 
     ContactPerson = new ContactPerson(); 
    } 
} 

:(已經離開了不需要的屬性)

public class Room 
{ 
    public int ID { get; set; } 
    public string RoomNumber { get; set; } 

    public virtual ICollection<Reservation> Reservations { get; set; } 
} 

聯繫人 :(已離開ou噸不必要屬性)

public class ContactPerson 
{ 
    public int ContactPersonID { get; set; } 

    public virtual ICollection<Reservation> Reservations { get; set; } 
} 

然後,我已經創建了一個DataContext類看起來像這樣:

public class DataContext : DbContext, IDataContext 
{ 
    public DataContext() : base("DataContext") 
    { 
    } 

    // DbSet to bookings 
    public DbSet<Reservation> Reservations { get; set; } 
    public DbSet<ContactPerson> ContactPersons { get; set; } 
    public DbSet<Room> Rooms { get; set; } 

    public void MarkAsModified(Reservation item) 
    { 
     Entry(item).State = EntityState.Modified; 
    } 

    public void CreateReservation(Reservation item) 
    { 
     Reservations.Add(item); 
    } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); 

     modelBuilder.Entity<Reservation>() 
      .HasMany(c => c.Room).WithMany(i => i.Reservations) 
      .Map(t => t.MapLeftKey("ReservationID") 
      .MapRightKey("RoomID") 
      .ToTable("RoomReservation")); 
    } 
} 

因爲它是一個多至室溫和預訂之間一對多的關係,一個共享的表將被創建。

我爲應用程序創建了一些測試數據,並使用遷移更新了數據庫。該Room模型應該在酒店房間創建一個表,像這樣的數據:應用程序啓動時

var rooms = new List<Room> 
     { 
      new Room {RoomNumber = "101", Beds = 1, RoomType = RoomTypeEnum.Single, Minibar = true, Occupied = true, Smoking = false}, 
      new Room {RoomNumber = "102", Beds = 1, RoomType = RoomTypeEnum.Single, Minibar = true, Occupied = true, Smoking = false}, 
      new Room {RoomNumber = "103", Beds = 1, RoomType = RoomTypeEnum.Single, Minibar = true, Occupied = false, Smoking = false}, 
      new Room {RoomNumber = "104", Beds = 2, RoomType = RoomTypeEnum.Double, Minibar = true, Occupied = false, Smoking = true},    
     }; 

rooms.ForEach(b => context.Rooms.AddOrUpdate(b)); 
context.SaveChanges(); 

這個測試數據應生成。問題是當我使用DataContext中的Reservations.Add添加預訂時,它會將新房間添加到Room表格中。

我想要的只是更新預訂表,聯繫表和共享表,哪些房間在預訂上。

因此,如果預約房間101(ID 1)和房間102(ID 2),這些ID應該在共享表內使用。

由於某些原因,當我添加一個預訂並且預訂有一個ID = 1(房間101)的房間時,它會爲該房間添加一個新生成的ID(ID = 5,因爲表中已經有4個房間),它不應該這樣做。它也更新共享表並使用此ID = 5,它應該使用ID = 1。

試圖儘可能地解釋這一點,希望有人能告訴我我的下一步行動。美好的一天:)

+0

你是否檢查了預訂的房間屬性是什麼調用'CreateReservation'什麼時候?是通過EF使用相同的DBContext加載的房間還是新的實例(例如,您在Reservation's Room集合中添加'New Room()')?您可能需要查看預訂的房間集合屬性並檢查其狀態(實體框架更改跟蹤狀態,如果它是新的,這可能會導致插入) –

+0

感謝您的回覆。我會在發佈之前用我的工作更新帖子。 – Mikkel

回答

0

快速一瞥,我注意到你的模型真的很複雜。你真的從房間和客戶導航屬性預訂?

複雜對象圖的寫(添加,更新,刪除)操作是實體框架中的一個痛點,尤其是當對象斷開時。

簡化您的模型並從房間和客戶中刪除ICollection預訂。

向您的數據訪問層添加其他方法以按房間和客戶進行預訂。

0

發現導致問題的問題。正如Bernhard Kircher向我解釋的那樣,上下文有問題。

解決了問題,得到所有房間的列表,過濾它,所以只有被選中的房間可以在列表中。

將該列表添加到預訂中。一些它如何工作,所以我猜想有關於國家的東西。

public bool Execute(Reservation reservation) 
    { 
     //Add correct rooms to reservation; 
     List<Room> roomsEntities = new List<Room>(); 

     foreach (var room in reservation.Room) 
     { 
      var roomsFound = _db.Rooms.Where(r => r.ID == room.ID).ToList(); 

      foreach (var ro in roomsFound) 
      { 
       roomsEntities.Add(ro); 
      } 
     } 

     //Add correct rooms to entity. 
     reservation.Room = roomsEntities; 

     try 
     { 
      _db.CreateReservation(reservation); 
      _db.SaveChanges(); 
     } 
     catch (Exception e) 
     { 
      return false; 
     } 

     return true; 
    } 

已經添加了其他的代碼看起來會經歷同樣的問題:)

+0

我很高興我的評論幫助了你,但你的代碼似乎是一個解決方法。也許你的數據模型並不理想(@KMC建議),但我對你的模型不太瞭解。但是我認爲是錯誤的是,事實上,你得到一個預留對象,其中有現有的房間,但你必須從數據庫重新加載它們以使其正常工作。這看起來像你的房間實體沒有附加到當前的DbContext(_db),這可能是EF試圖在數據庫上創建新實例的原因。根據我的經驗,這種「手動」解決方案/解決方法從長遠來看只會導致問題。 –