Using multiple models in a single controller [closed]
Asked Answered
C

1

0

I have used EF Designer from database to build my models from a database created for my project. For a single controller, I need to reference multiple models. An example of this is that there is a Users table which contains the user department and office. I need to reference two separate tables DepartmentPermissions and OfficePermissions to determine what data the user is able to see.

Here are examples of the auto generated models:

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated from a template.
//
//     Manual changes to this file may cause unexpected behavior in your application.
//     Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace Project.Models
{
    using System;
    using System.Collections.Generic;

    public partial class User
    {
        public int User_ID { get; set; }
        public string User_Username { get; set; }
        public string User_Department { get; set; }
        public string User_Office { get; set; }
    }
}

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated from a template.
//
//     Manual changes to this file may cause unexpected behavior in your application.
//     Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace Project.Models
{
    using System;
    using System.Collections.Generic;

    public partial class DepartmentPermission
    {
        public int DeptPerm_ID { get; set; }
        public string DeptPerm_Department { get; set; }
        public string DeptPerm_Role { get; set; }
    }
}

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated from a template.
//
//     Manual changes to this file may cause unexpected behavior in your application.
//     Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace Project.Models
{
    using System;
    using System.Collections.Generic;

    public partial class OfficePermission
    {
        public string OffPerm_OfficeID { get; set; }
    }
}

The first column in each table is a primary key in the database.

When creating a Controller using any of these autogenerated models all works fine, apart from I can only use one table.

I want to be able to check the user's department and office from the Users table and then check the Role associated with the user's department from the DepartmentPermissions table and then check whether the user's office is in the OfficePermissions table.

I read that I can build a View Model to create a new model which combines the models that I want to use so that I can get information from all relevant tables in the one controller.

My example ViewModel is:

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

namespace Project.Models
{
    public class HomeViewModel
    {            
        public IEnumerable<User> Users { get; set; }
        public IEnumerable<OfficePermission> OfficePermissions { get; set; }
        public IEnumerable<DepartmentPermission> DepartmentPermissions { get; set; } 
    }
}

When I attempt to create a Controller with this view model, I get errors saying:

User:: EntityType 'User' has no key defined. Define the key for this entity type. OfficePermission:: EntityType 'OfficePermission' has no key defined. Define the key for this entity type. DepartmentPermission:: EntityType 'DepartmentPermission' has no key defined. Define the key for this entity type. HomeViewModel:: EntityType 'HomeViewModel' has no key defined. Define the key for this entity type. Users: EntityType: EntitySet 'Users' is based on type 'User' that has no keys defined. OfficePermissions: EntityType: EntitySet 'OfficePermissions' is based on type 'OfficePermission' that has no keys defined. DepartmentPermissions: EntityType: EntitySet 'DepartmentPermissions' is based on type 'DepartmentPermission' that has no keys defined. HomeViewModels: EntityType: EntitySet 'HomeViewModels' is based on type 'HomeViewModel' that has no keys defined.

I could define Keys manually in the autogenerated files, however this would be undone when the database is changed and the files require automatic regeneration.

Is there a way to combine these autogenerated models in order to use them together in a controller?

Conferral answered 17/12, 2014 at 2:4 Comment(2)
Make sure that your model has a unique key differentiate each row.Carmella
Show the code you have tried!Rachal
S
1

You have different options you can use anyone of them

Use ViewModel

For view model you have to create a class and in this class you will define all models as properties of this class.Here are two classes.

public class EmployeeDetails
{
    [Required]
    [Display(Name = "Name")]
    public string Name { get; set; }

}

public class Employee
{
    public int Id { get; set; }
}

Here is viewmodel

public class ViewModel
{
    public Employee emp { get; set; }
    public EmployeeDetails empdet{ get; set; }
}

Now in Controller you will do like this

public ActionResult About()
{
        ViewModel vm = new ViewModel();
        vm.emp = new Employee();
        vm.empdet = new EmployeeDetails();
        return View(vm);
}

And in view you will receive it like this

@model ViewModel

And as you have stated that you are getting error table has no key defined you should properly define keys for the tables.

Use Tuple

Tuple is used to store different types.You can store your required classes object in it and pass to view

In controller

Tuple<int, string> tuple = new Tuple<int, string>(1, "Hello world");
return View(tuple);

In view you will receive it like this

@model Tuple<int,string>
Sirius answered 17/12, 2014 at 4:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.