繁体   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