0

Building web app with MVC5 using database first modeling approach. Unfortunately, the existing database that I'm building from has a table that's missing foreign key constraints, has extra primary keys and is not generally well formed. Because of this, when I build the MVC model, it can't automatically generate all of the necessary many to many relationships between the tables. I can't change the original table's definition.

I discovered the ability to create new associations through the MVC model diagram and the Model Browser, but it only seems to allow me to associate the tables and not specify the fields that join them. When I update the model, I get errors about the associations I created not mapping, without any details.

All the examples I can find for database first modeling start with well-formed and well-named tables, which is not always the case in real life.

Can someone explain or point me to a link about how to start with a database first model but then fix the problems or define the missing pieces so that the MVC model can build correctly?

Or maybe for this one table, I should just model the class directly? The only part of that I don't understand is where I define the details of the navigation properties so the model knows what tables and fields to join.

Jeff Wilson
  • 331
  • 3
  • 11
  • I found this on SO: http://stackoverflow.com/a/10237219/1582931. Somewhat of a database/code first hybrid approach. Another option would be to go full EF code-first on an existing database (https://channel9.msdn.com/Blogs/EF/Code-First-to-Existing-Database-EF6-1-Onwards-), and use the Fluent API to configure EF (https://msdn.microsoft.com/en-us/data/jj591617.aspx). – dotnetesse Apr 02 '16 at 11:57

1 Answers1

0

Directed by the comment above, I eventually determined a much better approach to creating an MVC app for an existing database that may not be designed the way you want to lay out your model.

I am using a CodeFirst approach of defining the Model classes directly instead of generating them from the existing database. Then, using Entity Framework mapping properties, I map each class and its individual properties to the existing table and fields. This lets me define the class however I wish, give it the property names I want and define the foreign keys that may not be defined in the database.

Here's some examples of classes that I created that map to existing database tables.

[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; }
}

The connection to the database is made via a DbContext class:

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

Entity Framework follows some conventions to "assume" certain properties, such as a field named id will be a key, but I chose to explicitly define all the mapping properties for clarity.

This approach allowed me to accomplish my goal of generating an MVC app for an existing database and follow our naming conventions without needing to change the database or add foreign key constraints to it.

Other reference links here: https://blogs.msdn.microsoft.com/efdesign/2010/06/01/conventions-for-code-first/

and here: https://msdn.microsoft.com/en-us/data/jj591617.aspx#1.1

Jeff Wilson
  • 331
  • 3
  • 11