2 different models - how to connect them in MVC 5? - c#

For my web app project, I have 2 models that are related to each other. Model Department is related to Model Employee. Each employee is assigned one department, while each department can have many employees. In the Departments view, I have an "Add new employee" option. When the add new employee button is clicked, a modal popup comes up which shows the Employees/Create view. My problem is I don't know how to link employee to department so that the employee automatically gets added to the department view next to the right department.
Right now, my Employee/Create view just gives the user a dropdown list of Departments to link the employee to. I want the employee to be automatically linked to the department when the "add employee" option is shown in the Departments view.
Here's the Department model:
public class Department
{
[Key]
public int ID { get; set; }
public string Name { get; set; }
public string BuildingLocation { get; set; }
public string DirectLine { get; set; }
public virtual ICollection<Employee> Employees { get; set; }
}
Here's the Employee model:
public class Employee
{
[Key]
public int EmployeeID { get; set; }
[ForeignKey("Department")]
public int DepartmentID { get; set; }
public string EmployeeFirstName { get; set; }
public string EmployeePosition { get; set; }
public string EmployeePhoneNo { get; set; }
public string EmployeeEmail { get; set; }
public virtual Department Department { get; set; }
}

I think you can create a EmployeeViewModel. For example:
public class Employee
{
public int EmployeeID { get; set; }
public int DepartmentID { get; set; }
public string EmployeeFirstName { get; set; }
public string EmployeePosition { get; set; }
public string EmployeePhoneNo { get; set; }
public string EmployeeEmail { get; set; }
public SelectListItem DepartmentList { get; set; }
}
When you click button add new employee, just set DepartmentId = DepartmentId that you selected. Or you can let the user changes Deparment.

You can create a ViewModel like this. Whenever you want to show employee details in the view then just map your data to this view model along with "DepartmentID" and "DepartmentName". To get "DepartmentName" you can join with department table and get department name.
public class EmployeeViewModel
{
public int EmployeeID { get; set; }
public string EmployeeFirstName { get; set; }
public string EmployeePosition { get; set; }
public string EmployeePhoneNo { get; set; }
public string EmployeeEmail { get; set; }
public int DepartmentID { get; set; }
public string DepartmentName { get; set; }
public virtual Department Department { get; set; }
}
To Get Department Name you can join with Employe table like this. (Note that I've used EntityFramework here to retrieve data)
var employeeList = from e in dbContext.Employees
join d in dbContext.Departments on e.DepartmentID equals d.DepartmentID
select new EmployeeViewModel
{
EmployeeID = e.EmployeeID,
EmployeeFirstName = e.EmployeeFirstName,
EmployeePosition = e.EmployeePosition,
EmployeePhoneNo = e.EmployeePhoneNo,
EmployeeEmail = e.EmployeeEmail,
EmployeePhoneNo = e.Name,
DepartmentID = e.DepartmentID,
DepartmentName = d.DepartmentName
};

Related

ASP.NET Relation between two tables

I'm new in Asp.Net and Entity Framework and i have a little issue.
I know u can help me , because its simple and i only know how to do it in PHP XD
I Have 2 models
public class Suppliers
{
public int ID { get; set; }
public int ID_Guard { get; set; }
public string Supplier{ get; set; }
public string Description { get; set; }
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd hh:mm tt}", ApplyFormatInEditMode = true)]
public DateTime Enter { get; set; }
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd hh:mm tt}", ApplyFormatInEditMode = true)]
public DateTime Exit { get; set; }
public virtual Guard Guard { get; set; }
}
public class Guard
{
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection<Suppliers> Suppliers{ get; set; }
}
controller
public class SuppliersController : Controller
{
private SuppliersContext db = new SuppliersContext();
public ActionResult Index()
{
return View(db.Suppliers.ToList());
}
}
And i wanna pass to the view the 2 table data and relate it
When i go to index show me all the suppliers data and show the Guard name( the person who registered the supplier enter and exit)
Well its solved
var results = from c in db.Suppliers
join cn in db.Guard on c.ID_Guard equals cn.ID
where (c.ID_Guard == cn.ID)
select new Models.MyViewModel{ Name= cn.Name, ID = c.ID, Supplier=c.Supplier, Description=c.Description, Enter=c.Enter, Exit=c.Exit};
follow the below code it works and seems same like yours also i added the link hope you find It helpful
public class Product
{
public Product() { Id = Guid.NewGuid(); }
public Guid Id { get; set; }
public string ProductName { get; set; }
public virtual ProductCategory ProductCategory { get; set; }
}
public class ProductCategory
{
public int Id { get; set; }
public string CategoryName { get; set; }
public virtual ICollection<Product> Products { get; set; }
}
/////view model///
public class ProductViewModel
{
public Guid Id { get; set; }
[Required(ErrorMessage = "required")]
public string ProductName { get; set; }
public int SelectedValue { get; set; }
public virtual ProductCategory ProductCategory { get; set; }
[DisplayName("Product Category")]
public virtual ICollection<ProductCategory> ProductCategories { get; set; }
}
follow the below tutorial
relationship model
for basic join use below query
var dealercontacts = from contact in table1
join table2 in table2 on contact.Id equals another.ID
select contact;

Dynamic menu from database in Asp.Net MVC

I'm a beginner and I want to display menu on the left side like This Website and when user clicks on any Category Name or its Sub Category Name I want to display Products related to the clicked category.
I've created 4 tables in my database.
Category
CategoryId(pk), CategoryName, Description, Icon
SubCategory
SubCategoryId(pk), SubCategoryName, Description, Icon,CategoryId(fk)
SubSubCategory
SubSubCategoryId(pk), SubSubCategoryName, Description, Icon, SubCategoryId(fk)
Products
ProductId(pk), Name, Price, Description, CategoryId(fk), SubCategoryId(fk), SubSubCategoryId(fk)
Category.cs Model
public partial class Category
{
public Category()
{
Products = new HashSet<Product>();
SubCategories = new HashSet<SubCategory>();
}
public int CategoryId { get; set; }
public string CategoryName { get; set; }
public string Description { get; set; }
public string Icon{ get; set; }
public virtual ICollection<Product> Products { get; set; }
public virtual ICollection<SubCategory> SubCategories { get; set; }
}
SubCategory.cs
public partial class SubCategory
{
public SubCategory()
{
Products = new HashSet<Product>();
SubSubCategories = new HashSet<SubSubCategory>();
}
[Key]
public int SubCategoryId { get; set; }
public string SubCategoryName { get; set; }
public int? CategoryId { get; set; }
public string Description { get; set; }
public string Icon{ get; set; }
public virtual Category Category { get; set; }
public virtual ICollection<Product> Products { get; set; }
public virtual ICollection<SubSubCategory> SubSubCategories { get; set; }
}
SubSubCategory.cs
public partial class SubSubCategory
{
public SubSubCategory()
{
Products = new HashSet<Product>();
}
[Key]
public int SubSubCategoryId { get; set; }
public string SubSubCategoryName { get; set; }
public int? SubCategoryId { get; set; }
public string Description { get; set; }
public string Image { get; set; }
public virtual ICollection<Product> Products { get; set; }
public virtual SubCategory SubCategory { get; set; }
}
Product.cs
public partial class Product
{
public int ProductId { get; set; }
public int? CategoryId { get; set; }
public int? SubCategoryId { get; set; }
public int? SubSubCategoryId { get; set; }
public string Name { get; set; }
[AllowHtml]
public string Description { get; set; }
public decimal? Price { get; set; }
}
You should try to first load the whole collection that you want to use in the current view.
Then use lambda expressions or predicates to sort the data into categories e.g
var list = wholeList.Where(i => i.category == "{category-name}");
then load this list to the view templates.
This method is both fast and convenient
On Click of Category, SubCategory, Sub Sub Category,
You should try below MVC way to load partials. Use appropriate overload of this.
#Ajax.ActionLink( ....)
Remember to use targetId in which element your called partial will load.
Your Layout must include jquery and jquery.unobtrusive-ajax. (jquery version must be higher than 1.9)

Add non-relational attribute to EF Entity (Join Operation)

I've a model as described below:
public class Student
{
public int Id { get; set; }
public string Level { get; set; }
public string Subject { get; set; }
public string School { get; set; }
public int CityId { get; set; } //from City
}
public class City
{
public int Id { get; set; }
public string City { get; set; }
public int StateId { get; set; } //from State
}
public class State
{
public int Id { get; set; }
public string State { get; set; }
public int CountryId { get; set; } //from Country
}
public class Country
{
public int Id { get; set; }
public string Country { get; set; }
}
I wants to query the Student Entity and needs to include the Country (Only Country) to the student Model.
The Database structure is like as above, I cannot change the DB Table Structure.
But I can able to edit the EF Entities above. Ultimately I need the Student info with country as a Student Entity, So that I can draw jqGrid and sort them based on country too.
Well if you can't modify your entity classes to add the corresponding navigation properties, you can try this:
var query = from student in context.Students
join city in context.Cities on student.CityId equals city.Id
join state in context.States on city.StateId equals state.Id
join country in context.Countries on state.CountryId equals country.Id
select new {
StudentId=student.Id,
Level=student.Level,
...
Country=country.Country
};
Or maybe:
select new {Student=student, Country=country.Country};
If your tables are related, I suggest you include the navigation properties to your model:
public class Student
{
public int Id { get; set; }
//...
public int CityId { get; set; } //from City
public virtual City City{get;set;}
}
public class City
{
public int Id { get; set; }
//...
public int StateId { get; set; } //from State
public virtual City City{get;set;}
public virtual ICollection<Student> Students{get;set;}
}
public class State
{
public int Id { get; set; }
//...
public int CountryId { get; set; } //from Country
public virtual Country Country {get;set;}
public virtual ICollection<City> Cities{get;set;}
}
public class Country
{
public int Id { get; set; }
public string Country { get; set; }
public virtual ICollection<State> States{get;set;}
}
That is not going to affect your current DB schema. This way is more easy to reach to the country name using a student instance (as #SteveGreene show in his answer):
var countryName=student.City.State.Country.Country;
You can project that into an anonymous object or viewmodel:
var studentWithCountry = context.Student.Where(Id = myVar.Id)
.Select(s => new { Level = s.Level,
Subject = s.Subject,
...
Country = s.City.State.Country.Country });

EntityFramework changing my query - EntityCommandExecutionException

I'm getting a 'EntityCommandExecutionException' and
An error occurred while executing the command definition. See the inner exception for details.
with an inner message of
Invalid column name 'Department_ID'
This seems to be the query executed from this line of code:
List<Employee> _employees = employeeContext.Employees.ToList();
SELECT [Extent1].[EmployeeID] AS [EmployeeID],
[Extent1].[Name] AS [Name],
[Extent1].[Gender] AS [Gender],
[Extent1].[City] AS [City],
[Extent1].[DepartmentID] AS [DepartmentID],
[Extent1].[DateOfBirth] AS [DateOfBirth],
[Extent1].[Department_ID] AS [Department_ID]
FROM [dbo].[tblEmployee] AS [Extent1]
This is wrong considering there is no Department_ID, I have no idea where it is getting this from. This is the Employee class model:
[Table("tblEmployee")]
public class Employee
{
public int EmployeeID { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public string City { get; set; }
public int DepartmentID { get; set; }
public DateTime DateOfBirth { get; set; }
}
[Table("tblDepartment")]
public class Department
{
public Int16 ID { get; set; }
public string Name { get; set; }
public List<Employee> Employees { get; set; }
}
Not sure what to do. Any ideas?
The Department_ID is coming by virtue of the relationship in your Department class. You have a List Employees there which automatically assumes a column called Department_ID in your Employee table.
What you need to do is add a virtual property called Department in your Employee table instead of adding the DepartmentID
[Table("tblEmployee")]
public class Employee
{
public int EmployeeID { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public string City { get; set; }
public virtual Department Department { get; set; }
public DateTime DateOfBirth { get; set; }
}
If you need to maintain the column name as DepartmentID or you need access to the property DepartmentID in code, then you need to use the ForeignKey attribute as shown below:
public class Employee
{
public int EmployeeID { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public string City { get; set; }
public int DepartmentID { get; set; }
[ForeignKey("DepartmentID")]
public virtual Department Department { get; set; }
public DateTime DateOfBirth { get; set; }
}
I would also recommend that you maintain the List as virtual.

How to get details of particular records from multiple tables in asp.net MVC

I have two tables StudentPersonalInformation and EducationQualification
Here in MVC, I have create two model classes StudentPersonalInformation.cs and EducationQualification.cs, here I create the object of both classes in one wrapper class and that class Name is StudentInfo.cs
public class StudentPersonalInfo {
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string StudentFirstName { get; set; }
public string StudentLastName { get; set; }
public int Age { get; set; }
public string BloodGroup { get; set; }
public string Address { get; set; }
}
public class EducationQualification {
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Graduation { get; set; }
public int Grad_Marks_obtain { get; set; }
public string Grad_passing_year { get; set; }
public stringPost Graduation { get; set; }
public int PG_Marks_obtain { get; set; }
public string PG_passing_year { get; set; }
}
public class StudentInfo
{
public StudentPersonalInfo PersonalInfo { get; set; }
public EducationQualification EducationalQualification { get; set; }
}
This is the DBContext class:
public class StudentDbContext:DbContext
{
public DbSet<StudentPersonalInfo> StudentPersonalInfos { get; set; }
public DbSet<EducationQualification> EducationQualifications { get; set; }
}
And My Question is:
How to display the details by id of particular students from both tables in one view.
Please tell me how to do this….
You should make a ViewModel and in the controller action you should populate all the properties you want the view to have.
public class MyViewModelWithMultipleLists
{
public List<StudentPersonalInfo> Students{ get; set; }
public List<EducationQualification> Educations{ get; set; }
//etc
}
First you need to create a relationship between Student and Qualification by adding a navigation property to EducationQualification, assuming each qualification has 1 student.
public virtual Student Student {get; set;}
If a student can have more than one qualification, your StudentInfo model would be more likely to look like this:
public StudentPersonalInfo PersonalInfo { get; set; }
public List<EducationQualification> EducationalQualification { get; set; }
So then you you can query the db, and because you have created a relationship between student and qualification, your query will look something like:
var model= (from s in Student
where s.Id = id
select new StudentInfo
{
PersonalInfo = s,
EducationalQualification = s.EducationQualification.ToList()
}).FirstOrDefault()
You would pass the results:
return View(model);
to a strongly typed View:
#model StudentInfo
#Html.DisplayFor(x => x.PersonalInfo.StudentFirstName)
...etc

Categories

Resources