簡體   English   中英

ASP.net MVC 4 EF5中的代碼優先方法混亂

[英]Code First Approach Confusion in ASP.net MVC 4 EF5

在過去的十個小時左右的時間里,我一直在努力尋找並研究實現關系代碼優先的數據庫結構和類結構的最佳方法。

不幸的是,到目前為止,ASP和Google擊敗了我!

我將附上一個UML圖,以更好地解釋我對系統的設想,實際上,我只是在尋找有關我應該采用的方法的說明,如果需要創建其他類(如View),則應保留某些功能。模型,領域模型,如何將所有這些鏈接到數據庫上下文中,我是否需要自己創建所有CRUD實現? 等等等

(我從Java的背景開始就使用過ArrayList,並且最清楚的是,我一直在閱讀ICollections和IEnumerables,但無法確定使用哪個?

UML圖

從我以前的嘗試,到目前為止,我已經嘗試過:

  • 一個實現DbContext類的類,其中包含所有RoomBunkBooking類的DbSet '。
  • 每個類似於上面存儲類數據的“實體”的單個域類(這是正確的術語嗎?),我已經設法借助add-migrations從這些數據庫中生成數據庫,但是它如何鏈接Room和使用ICollection Bunk類似乎沒有提供任何方法來從Room.Bunks ICollection中訪問與Room Room.Bunks
  • 我還擁有RoomHelperBunkHelper類,它們使用LINQ語句來嘗試手動檢索各種數據以及標准CRUD方法。 這似乎令人困惑,並讓我覺得我可能會缺少為我自動生成的內容?

很多東西,但是我真的很努力,任何幫助都非常感激:)

正如某些人要求的,以下是我創建的代碼

Bunk.cs

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using TestApplication.Models.Enums;

namespace TestApplication.Models
{
    public class Bunk
    {
        [Key]
        public Int32 BunkId { get; set; }
        public BunkStatus BunkStatus { get; set; }
    }
}

Room.cs

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using TestApplication.Models.Enums;

namespace TestApplication.Models
{
    public class Room
    {
        [Key]
        public Int32 RoomId { get; set; }
        public String RoomName { get; set; }
        public Gender RoomGender { get; set; }
        public RoomStatus RoomStatus { get; set; }
        public ICollection<Bunk> Bunks { get; set; }
    }
}

DatabaseContext.cs

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;

namespace TestApplication.Models
{
    public class DatabaseContext : DbContext
    {
        public DbSet<Room> Rooms { get; set; }
        public DbSet<Bunk> Bunks { get; set; }
    }
}

此代碼生成了以下數據庫結構,該數據庫結構不允許我訪問Room.Bunks.All() (作為我誤解的概念的示例用法)

數據庫預覽

這些是您需要的類:

public class Room
{
    [Key]
    public int RoomId { get; set; }

    public string RoomName { get; set; }

    public GenderEnum Gender { get; set; }

    public RoomStatusEnum RoomStatus { get; set; }

    public virtual ICollection<Bunk> Bunks { get; set; }

    // convenience
    public virtual ICollection<Booking> Bookings { get; set; }
}

public class Bunk
{
    [Key]
    public int BunkId { get; set; }

    public BunkStatusEnum BunkStatus { get; set; }

    [ForeignKey("Room")]
    public int RoomId { get; set; }
    public virtual Room Room { get; set; }

    // convenience
    public virtual ICollection<Booking> Bookings { get; set; }
}

public class Booking
{
    [Key]
    public int BookingId { get; set; }

    [ForeignKey("UserProfile")]
    public int UserProfileId { get; set; }
    public UserProfile UserProfile { get; set; }

    [ForeignKey("Bunk")]
    public int BunkId { get; set; }
    public Bunk Bunk { get; set; }

    public int Duration { get; set; }

    [ForeignKey("Preferred_Room")]
    public int RoomId { get; set; }
    public Room Preferred_Room { get; set; }

    public Decimal Price { get; set; }

    public BookStatusEnum BookingStatus { get; set; }
}

我唯一要提醒您的是“ Booking Room的外鍵。 如果一個Bunk只能屬於一個Room ,那么您已經通過Bunk.Room選擇了Room 通過向Booking for Room添加另一個外鍵,您將創建一個雙鏈接,這將使刪除工作變得很困難。

我將在上面的評論中進行擴展,因為在發布代碼之后,看來您確實沒有將導航屬性虛擬化。

您需要使用某種查詢從數據庫中獲取房間對象。 例如:

using (var context = new DatabaseContext()){
    var room = context.Rooms.First();
}

在上面的示例中,您最終將獲得一個room對象,但是實體框架不會自動拉回所有相關實體(例如Bunks)。在很多情況下,這可能會過大,在某些情況下,這是不可能的。 您需要明確告知實體框架您希望帶回哪些相關實體。 例如:

using (var context = new DatabaseContext()){
    var room = context.Rooms.Include("Bunks").First();
}

在此示例中,實體框架將作為查詢的一部分加載Bunks,您將能夠使用語法room.Bunks()訪問Bunks。

最后,如果您願意的話,您也可以使用原始示例。 您將利用一種稱為“延遲加載”的功能,即實體框架僅在您首次訪問導航屬性(即room.Bunks)時才加載相關的實體。 這將需要2次調用數據庫。 第一次打電話來獲得房間,第二次得到鋪位。

僅當將ICollection屬性更改為虛擬時,這才起作用:

public ICollection<Bunk> Bunks { get; set; }

需要成為

public virtual ICollection<Bunk> Bunks { get; set; }

這是因為實體框架需要知道您何時首次訪問Bunks集合。 實體框架通過返回從Room類(而不是Room類)派生的對象來實現此目的,並且它使用首次訪問時運行的代碼覆蓋Bunks屬性。 如果此屬性不是虛擬屬性,則它將無法執行此操作,因此它將無法正常工作

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM