Hi I have three classes as objects which go into the database.
public class Employees
{
public int Id { get; set;}
public string Name { get; set;}
public string SocialSecurityNumber{ get; set;}
public DateTime DateOfBirth { get; set;}
}
public class Education
{
public int Id { get; set;}
public string EmployeeId { get; set;}
public string EducationLevel{ get; set;} // this will be a drop down list
public string University { get; set;}
public string FieldOfStudy { get; set;}
}
public class Experience
{
public int Id { get; set;}
public int EmployeeId { get; set;}
public string Employer{ get; set;}
public DateTime From { get; set;}
public DateTime To { get; set;}
public string JobRole { get; set;}
}
Then I have the DBContext class defined as:
public class AppDb : DbContext
{
public DbSet<Employee>Employees{ get; set;}
public DbSet<Education> Educations { get; set;}
public DbSet<Experience> Experiences {get; set;}
}
What my app needs to do now is offer a Create Employee form on the home page which lets the user fill in all the details pertaining to him. That is Employee details , Education and Experience against the employee object in one single form in Home/Index View.
Any help will be appreciated.
Create new class in the Model folder.
Add 3 properties for Employees, Education and Experience and build your project.
In the action method in the controller (Index for example), fill that class with your data and 'return View(yourFilledClass)'
right click on the controller method (Index) and add View
Bind that view to the new class and select Details in the dropdown
Now you have a view for displaying all the details of the new class you've just populated
It's quite the same for Edit, delete and add
Hope it helps :)
Related
I have the following models:
public class Item {
public string ItemID {get; set;}
public decimal AvailableQuantity {get; set;}
}
public class Element {
public string ElementID {get; set;}
[ForeignKey("Item")]
public string ItemID { get; set; }
public virtual Item Item { get; set; }
public decimal Quantity {get; set;}
}
I want the Quantity field from Element to be always less than the Item that it's representing. I tried using the Foolproof data annotation:
[Foolproof.LessThanOrEqualTo(Item.AvailableQuantity)]
public decimal Quantity { get; set; }
but I get the following error:
CS0120: An object reference is required for the non-static field, method, or property 'Element.Item'
What can I do to satisfy this condition? I want to use it for data validation in form.
I think you have another problem too:
public class Item {
public string ItemID {get; set;}
public decimal AvailableQuantity {get; set;}
}
public class Element {
public string ElementID {get; set;}
[ForeignKey("Item")] // you dont have a property called Item here except from the Item
object which cant be used as a foreign key.
public string ItemID { get; set; }
[ForeignKey("ItemID")] //this will work
public virtual Item Item { get; set; }
public decimal Quantity {get; set;}
}
As for data annotation Foolproof has options but i think you cant do it on these models.
Try it Creating a ViewModel so the properties comparing are in the same model;
This may work:
[GreaterThan("Quantity")]
Suppose I have a model like the following:
public class A{
public int ID { get; set;}
[Required]
public string Name { get; set;}
}
And I have another model like the following:
public class B{
public int ID { get; set;}
[Required]
public string Name { get; set;}
[Required]
public int AId { get; set;}
public string Type { get; set;}
[Required]
public int SlNo { get; set;}
}
Basically, I want to have a One-to-many, Parent-Child relationship between A and B, so that AId will act like a foreign key to A, and the same value of AId may be present in multiple instances of B.
How to achieve this in Entity Framework CF 5, ASP.NET MVC 4?
Inside of class B, just add a navigation property to class A. Then the code-first conventions will be able to infer the relationship. This ought to do it:
public class A{
public int ID { get; set;}
[Required]
public string Name { get; set;}
public virtual ICollection<B> Bs {get; set;}
}
public class B{
public int ID { get; set;}
[Required]
public string Name { get; set;}
[Required]
public int AId { get; set;}
public string Type { get; set;}
[Required]
public int SlNo { get; set;}
public virtual A A { get; set; }
}
I am fairly new to using Code First approach with entity framework and I know that I you have a many to many relationship like the entities below, the EF will create the intermediary table automatically:
class Post {
...
public virtual ICollection<Category> Categories {get; set;}
...
}
class Category {
...
public virtual ICollection<Post> Posts {get; set;}
...
}
However, if in the intermediary table I need to have extra data fields, one possible way (which I currently like, maybe because I am unaware of better ways) would be defining a new Entity of my own, like:
class Posts_Categories {
public int Id {get; set;}
public int CategoryId {get; set;}
public int PostId {get; set;}
public string Exrtafield1 {get; set;}
public int ex extraField2 {get; set;}
...
public virtual Post Post {get; set;}
public virtual Category Category {get; set;}
}
Using this approach, EF does create my custom intermediary table, but it also creates another one of its own called "PostsCategories" which only contains a foreign key to Post_Id and another to Category_Id.
How do I make it not create that extra one and use the one I have defined?
Is this a good way to manage Many to Many relationships with extra data fields??
you should use one to many relation like this :
public class Post
{
public System.Int32 PostId { get; set; }
[InverseProperty("Post")]
public virtual ICollection<Posts_Category> PostCategories { get; set; }
}
public class Category
{
public System.Int32 CategoryId { get; set; }
[InverseProperty("Category")]
public virtual ICollection<Posts_Category> PostCategories { get; set; }
}
public class Posts_Category
{
public System.Int32 PostId { get; set; }
public System.Int32 CategoryId { get; set; }
[ForeignKey("PostId")]
[InverseProperty("PostCategories")]
public virtual Post Post { get; set; }
[ForeignKey("CategoryId")]
[InverseProperty("PostCategories")]
public virtual Category Category { get; set; }
}
I needed to expand a bit on Iraj's answer to make it work. Another modification is that I'm including the default ApplicationUser as one of my tables.
So the relation is ApplicationUser 1-∞ IdeaVote ∞-1 Idea (i.e. there are users and ideas, users can vote on ideas, and each vote is represented with a connection between an ApplicationUser and an Idea.
public class Idea
{
[Key]
public int Id { get; set; }
// This is an ordinary data field
public string Text { get; set; }
[InverseProperty("Idea")]
public virtual ICollection<IdeaVote> Votes { get; set; }
}
public class IdeaVote
{
[Key]
public int Id { get; set; }
public int IdeaId { get; set; }
[ForeignKey("IdeaId")]
[InverseProperty("Votes")]
public virtual Idea Idea { get; set; }
public string UserId { get; set; }
[ForeignKey("UserId")]
[InverseProperty("Votes")]
public virtual ApplicationUser User { get; set; }
}
public class ApplicationUser : IdentityUser
{
[InverseProperty("User")]
public virtual ICollection<IdeaVote> Votes { get; set; }
// Default stuff
}
It is normal for it to create that PostsCategories table for the relation between the two, and you are going to want that. If c is a Category, you'll be able to do things like c.Posts
Normally you would not create your own table manually for that. What kinds of data would you be keeping in the "extra" fields? I would probably move the fields to one of the other tables and drop that one. Most many to many relationship tables do not contain extra fields.
I have a model imported from entity data framework
public class person
{
public string Name {get; set;}
}
and a viewmodel inherited from person
public class personviewmodel:person
{
public int Applied {get; set;}
}
I use personviewmodel as the model in my view. I would like to add error validation (data annotation) to 'Name' property without modifying the generated 'person' class. Can you please help get this?
You can implement validation as follows. But thing here you are not inheriting Person using person's object as is. Hope this will help you.
public class Person
{
[Required(ErrorMessage = "Message")]
public string Name {get; set;}
}
public class personviewmodel
{
public int Applied {get; set;}
public Person Person {get; set;}
}
or
public class Person
{
public string Name {get; set;}
}
public class Personviewmodel : Person
{
public int Applied {get; set;}
[Required(ErrorMessage="Name is required")]
public new string Name {get; set;}
}
or
public class Person
{
public virtual string Name {get; set;}
}
public class Personviewmodel : Person
{
public int Applied {get; set;}
[Required(ErrorMessage="Name is required")]
public override string Name {get; set;}
}
I have this selfreferencing Model:
public class AddressDataViewModel
{
[Required]
public String Country {get; set;}
public String Town {get; set;}
public AddressDataViewModel AdditionalAddress {get; set;}
}
Problem is that the Required attribute is also applicated to the Country property of self referenced object AdditionalAddress and so on.
Is there some easy way to suppress this? I only want Required validation to first of the hierarchy.
Thanks.
You could solve this with a base and derived class:
public abstract class AddressDataViewModel
{
public virtual String Country {get; set;}
public String Town {get; set;}
}
public class PrimaryAddressDataViewModel : AddressDataViewModel
{
[Required]
public Overrides String Country {get; set;}
}
public class AdditionalAddressDataViewModel : AddressDataViewModel
{
}
public class AddressesDataViewModel
{
public PrimaryAddressDataViewModel PrimaryAddress {get;set;}
IEnumerable<AdditionalAddressDataViewModel> AdditionalAddresses {get;set;}
}