C# ASP.net MVC 4 EF5中的代码优先方法混乱

C# ASP.net MVC 4 EF5中的代码优先方法混乱,c#,asp.net,asp.net-mvc,entity-framework,C#,Asp.net,Asp.net Mvc,Entity Framework,在过去的10个小时里,我一直在努力找出并研究实现我所追求的关系型代码优先数据库结构和类体系结构的最佳方法 不幸的是,到目前为止,ASP和谷歌打败了我 我会附上一个UML图来更好地解释我对系统的设想,我只是想解释一下我应该采取的方法,在哪里保留某些功能,如果我需要创建其他类,如视图模型、域模型,如何将所有这些链接到数据库上下文,我需要自己创建所有CRUD实现吗?等等 (我使用过ArrayList,因为我有Java背景,最清楚的是,我一直在阅读ICollections和IEnumerables,但无

在过去的10个小时里,我一直在努力找出并研究实现我所追求的关系型代码优先数据库结构和类体系结构的最佳方法

不幸的是,到目前为止,ASP和谷歌打败了我

我会附上一个UML图来更好地解释我对系统的设想,我只是想解释一下我应该采取的方法,在哪里保留某些功能,如果我需要创建其他类,如视图模型、域模型,如何将所有这些链接到数据库上下文,我需要自己创建所有CRUD实现吗?等等

(我使用过ArrayList,因为我有Java背景,最清楚的是,我一直在阅读ICollections和IEnumerables,但无法决定使用哪一个

从我以前的尝试到目前为止,我已经尝试:

  • 实现
    DbContext
    类的单个类,其中包含
    DbSet
    ,用于所有
    房间
    床铺
    预订
  • 每个“实体”都有一个域类(这是正确的术语吗?)它存储了与上面类似的类数据,我通过
    add migrations
    的帮助从这些类生成了数据库,但是它使用
    ICollection
    链接
    Room
    Bunk
    类的方式似乎没有提供任何从
    访问
    Room
    的方法>Room.Bunks
    i从数据库检索床铺时收集
  • 我还有
    RoomHelper
    BunkHelper
    类,它们使用
    LINQ
    语句尝试手动检索各种数据以及标准的CRUD方法。这似乎让我感到困惑,让我觉得我可能缺少了一些自动生成的东西
这是很多,但我真的很挣扎,任何帮助都非常感谢:)

正如一些人所要求的,下面是我创建的代码

床铺

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; }
    }
}
C室

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; }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.ComponentModel.DataAnnotations;
使用System.Linq;
使用System.Web;
使用TestApplication.Models.Enum;
命名空间TestApplication.Models
{
公共教室
{
[关键]
public Int32 RoomId{get;set;}
公共字符串RoomName{get;set;}
公共性别房间性别{get;set;}
公共RoomStatus RoomStatus{get;set;}
公共ICollection铺位{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; }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Data.Entity;
使用System.Linq;
使用System.Web;
命名空间TestApplication.Models
{
公共类DatabaseContext:DbContext
{
公共数据库集房间{get;set;}
公共DbSet铺位{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; }
}
公共教室
{
[关键]
public int RoomId{get;set;}
公共字符串RoomName{get;set;}
公共GenderEnum性别{get;set;}
公共RoomStatus枚举RoomStatus{get;set;}
公共虚拟ICollection铺位{get;set;}
//方便
公共虚拟ICollection预订{get;set;}
}
公务舱铺位
{
[关键]
公共int BunkId{get;set;}
公共BunkStatusEnum BunkStatus{get;set;}
[外键(“房间”)]
public int RoomId{get;set;}
公共虚拟房间{get;set;}
//方便
公共虚拟ICollection预订{get;set;}
}
公共课预订
{
[关键]
public int BookingId{get;set;}
[外键(“用户配置文件”)]
public int UserProfileId{get;set;}
公共用户配置文件用户配置文件{get;set;}
[外键(“下铺”)]
公共int BunkId{get;set;}
公共铺位{get;set;}
公共整数持续时间{get;set;}
[外宾房(“首选房”)]
public int RoomId{get;set;}
公共房间首选房间{get;set;}
公共十进制价格{get;set;}
公共BookStatusEnum BookingStatus{get;set;}
}

我唯一要提醒您的是
预订
房间
的外键。如果一个
铺位
只能属于一个
房间
,那么您已经通过
铺位房间
选择了
房间
。通过为
房间
预订
添加另一个外键,您正在创建一个双链接,这将使删除操作变得非常困难。

我将在上面展开我的评论,因为在发布代码之后,您似乎确实没有将导航属性虚拟化

您需要使用某种查询从数据库中获取房间对象。例如:

using (var context = new DatabaseContext()){
    var room = context.Rooms.First();
}
在上面的示例中,您将得到一个房间对象,但实体框架不会自动收回所有相关实体(即床铺)。。在很多情况下,这样做是过分的,在某些情况下是不可能的。您需要明确地告诉实体框架您希望它带回哪些相关实体。e、 g:

using (var context = new DatabaseContext()){
    var room = context.Rooms.Include("Bunks").First();
}
在本例中,实体框架将加载床铺作为查询的一部分,您可以使用syntax room.Bunks()访问床铺

最后,如果您愿意的话,您也可以使用原始示例。您可以利用一种称为延迟加载(Lazy-loading)的方法,即当您第一次访问导航属性(即room.Bunks)时,实体框架将只加载相关的实体。这将需要对数据库进行2次调用。第一个打电话要房间,第二个打电话要铺位

仅当您将ICollection属性更改为虚拟时,此操作才有效:

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