MVC首先从数据库编辑模型关系

时间:2016-04-02 00:19:39

标签: asp.net-mvc-4

使用数据库优先建模方法使用MVC5构建Web应用程序。不幸的是,我构建的现有数据库有一个表缺少外键约束,有额外的主键,通常不是很好。因此,当我构建MVC模型时,它无法自动生成表之间所有必需的多对多关系。我无法更改原始表格的定义。

我发现了通过MVC模型图和模型浏览器创建新关联的能力,但它似乎只允许我关联表而不指定连接它们的字段。当我更新模型时,我得到的错误是我创建的关联没有映射,没有任何细节。

我可以找到的数据库优先建模的所有示例都是从结构良好且命名良好的表开始的,现实情况并非总是如此。

有人可以向我解释或指向一个关于如何从数据库第一模型开始,然后修复问题或定义缺失部分以便MVC模型可以正确构建的链接吗?

或者也许对于这一张桌子,我应该直接对这个类进行建模?我不了解的唯一部分是我定义导航属性的详细信息,以便模型知道要加入的表和字段。

1 个答案:

答案 0 :(得分:0)

在上述评论的指导下,我最终确定了一种更好的方法,可以为现有数据库创建一个MVC应用程序,该应用程序的设计可能与您想要布置模型的方式不同。

我正在使用CodeFirst方法直接定义Model类,而不是从现有数据库生成它们。然后,使用Entity Framework映射属性,我将每个类及其各个属性映射到现有的表和字段。这让我可以定义我想要的类,给它我想要的属性名称,并定义可能没有在数据库中定义的外键。

以下是我创建的映射到现有数据库表的类的一些示例。

[Table("uofs00137_contacts")]
public partial class Contact
{
    [Key]
    [Column("id")]
    public int ID { get; set; }

    [Column("first_name")]
    [StringLength(30)]
    [Display(Name = "First Name")]
    public string FirstName { get; set; }

    [Column("last_name")]
    [StringLength(30)]
    [Display(Name = "Last Name")]
    public string LastName { get; set; }

    [Column("organisation")]
    [StringLength(30)]
    [Display(Name = "Organization")]
    public string Organization { get; set; }

    [Column("title")]
    [StringLength(30)]
    [Display(Name = "Job Title")]
    public string JobTitle { get; set; }

    [Column("email")]
    [StringLength(40)]
    [Display(Name = "Email")]
    public string Email { get; set; }

    [Column("status_code")]
    [StringLength(1)]
    [Required]
    [Display(Name = "Contact Status Code")]
    public string StatusCode { get; set; }

    [Display(Name = "Full Name")]
    public string FullName
    {
        get
        {
            return FirstName + " " + LastName;
        }
    }

    public virtual ICollection<DepartmentContact> DepartmentContacts { get; set; }
}

[Table("uofs00137_dept_contacts")]
public partial class DepartmentContact
{
    [Key]
    [Column("id")]
    public int ID { get; set; }

    [Column("department_code")]
    [StringLength(7)]
    [ForeignKey("VirtualDepartment")]
    [Display(Name = "Department Code")]
    public string DepartmentCode { get; set; }

    [Column("contact_id")]
    [ForeignKey("Contact")]
    [Display(Name = "Contact ID")]
    public int ContactID { get; set; }

    [Column("status_code")]
    [StringLength(1)]
    [Required]
    [Display(Name = "Department Contact Status Code")]
    public string StatusCode { get; set; }

    [Display(Name = "Department Contact Status")]
    public string StatusDesc
    {
        get
        {
            if (StatusCode == "I")
                return "Inactive";
            else if (StatusCode == "A")
                return "Active";
            else
                return "Unknown Status";
        }
    }

    public virtual VirtualDepartment VirtualDepartment { get; set; }
    public virtual Contact Contact { get; set; }
}

与数据库的连接是通过DbContext类进行的:

 public partial class AccountingAdminEntities : DbContext
{
    public AccountingAdminEntities() : base("name=AccountingAdminEntities")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // This is necessary so that as you add new items to the context
        // you don't get the following exception:
        //   The model backing the AccountingAdminEntities context has
        //   changed since the database was created. Consider using Code
        //   First Migrations to update the database.
        Database.SetInitializer<AccountingAdminEntities>(null);
        base.OnModelCreating(modelBuilder);
    }

    public virtual DbSet<Contact> Contacts { get; set; }
    public virtual DbSet<DepartmentContact> DepartmentContacts { get; set; }
}

实体框架遵循一些约定来“假设”某些属性,例如名为id的字段将是一个键,但为了清楚起见,我选择明确定义所有映射属性。

这种方法使我能够实现为现有数据库生成MVC应用程序的目标,并遵循我们的命名约定,而无需更改数据库或向其添加外键约束。

此处的其他参考链接: https://blogs.msdn.microsoft.com/efdesign/2010/06/01/conventions-for-code-first/

在这里: https://msdn.microsoft.com/en-us/data/jj591617.aspx#1.1