RaviKant Hudda RaviKant Hudda - 1 month ago 7
C# Question

How to Pass model data to layout page in mvc with Entity Framework?

I am stuck in a problem where I want to show model's properties on layout page. With the reference of this answer I tried to implement the model as the following way


CompanyProfile Model


[Table("tblCompany")]
public abstract class CompanyProfile
{
[Key]
public int CompanyId { get; set; }
public string CompanyName { get; set; }
public string CompanyLogo { get; set; }
public string TitlePic { get; set; }
public string CopyText { get; set; }
public string RegText { get; set; }
}


and


Employee model is like


[Table("tblEmployee")]
public class Employee:CompanyProfile
{
[Key]
public int EmpID { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public int DepartmentId { get; set; }
public string EmpNo { get; set; }
}


and


Department model is like


[Table("tblDepartment")]
public class Department:CompanyProfile
{
[Key]
public int DeptID { get; set; }
public string DeptName { get; set; }
}


as you can see both the models are inherited from


CompanyProfile


model. Now my problem is when I am trying to access CompanyProfile model in my controller it is giving me an error


"Invalid column name 'CompanyId'.\r\nInvalid column name 'CompanyId'"


because entity framework is creating the table on behalf of model and joining these tables and tries to find


CompanyId in tblEmployee


to the best of my knowledge.


SampleContext class is like


public class SampleContext:DbContext
{
public DbSet<Employee> empList { get; set; }
public DbSet<Department> deptList { get; set; }
public DbSet<CompanyProfile> Profile { get; set; }
}



and HomeController is like


SampleContext context=new SampleContext();
public ActionResult Index()
{
CompanyProfile profile;
if (Session["Profile"] == null)
{
Session["Profile"] = context.Profile.FirstOrDefault();
}
profile = (CompanyProfile)Session["Profile"];
return View(profile);
}



Here is my Layout.cshtml code


@model ShareLayoutToContent.Models.CompanyProfile
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
<link rel="shortcut icon" href="@Url.Content(Model.TitlePic)">
</head>


Now can you please provide where I am committing mistakes. Thanks in advance.

Answer

Looking at the link you provided in your question, the intention is to create a main model that will allways be the same e.g.:

public class BaseModel
{
    public CompanyProfile Profile { get; set; }
    public Employee Employee { get; set; }
    public Department Department { get; set; }
}

So your entity's would be:

[Table("tblCompany")]
public class CompanyProfile
{
    [Key]
    public int CompanyId { get; set; }
    public string CompanyName { get; set; }
    public string CompanyLogo { get; set; }
    public string TitlePic { get; set; }
    public string CopyText { get; set; }
    public string RegText { get; set; }
}

[Table("tblEmployee")]
public class Employee
{
    [Key]
    public int EmpID { get; set; }
    public string Name { get; set; }
    public string Gender { get; set; }
    public int DepartmentId { get; set; }
    public string EmpNo { get; set; }
    public CompanyProfile profile { get; set; } //if needed
}

[Table("tblDepartment")]
public class Department
{
    [Key]
    public int DeptID { get; set; }
    public string DeptName { get; set; }
    public CompanyProfile profile { get; set; } //if needed
}

And then you'll be able to create your MainView based upon that BaseModel.

HomeController:

SampleContext context=new SampleContext();
public ActionResult Index()
{
    CompanyProfile profile;
    if (Session["Profile"] == null)
    {
       Session["Profile"] = context.Profile.FirstOrDefault();
    }
    profile = (CompanyProfile)Session["Profile"];
    return View(new BaseModel { Profile = profile });
}

View:

@model ShareLayoutToContent.Models.BaseModel
<head>
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
    <link rel="shortcut icon" href="@Url.Content(Model.Profile.TitlePic)">
</head>