ASP.NET MVC 6 Update Multiple Tables from One View - asp.net

I’m coming from an intermediate C++ background (and to a lesser extent, C#) and wanted to try to build a project in Asp.net MVC 6 with EF 7 – not realizing how completely different it is from simple C# forms. I’ve stumbled through and researched a lot but since I’m a total noob I’m stumped at this point.
I have the following models:
public class Shift
{
public int ShiftId { get; set; }
//other properties
public virtual ICollection<ShiftActivity> ShiftActivity { get; set;}
}
public class ShiftActivity
{
public int ShiftActivityID { get; set; }
public DateTime StartTime { get; set; }
public int ShiftID { get; set; }
public int ActivityID { get; set; }
public int LocationID { get; set; }
public virtual Shift Shift { get; set; }
public virtual Activity Activity { get; set; }
public virtual Location Location { get; set; }
}
public class Activity
{
public int ActivityID { get; set; }
public string ActivityName { get; set; }
public virtual ICollection<ShiftActivity> ShiftActivity { get; set; }
}
public class Location
{
public int LocationID { get; set; }
public string LocationName { get; set; }
public string LocationAddress { get; set; }
public int locationZip { get; set; }
public virtual ICollection<ShiftActivity> ShiftActivity { get; set; }
}
I would like to create a shift and be able to input all the required fields all from one view. For instance, when I create the shift, I need to pick the type of location and activity to add to the ShiftActivity table which is then updated. Eventually I would like to be able to dynamically add additional activities (I’m assuming I’ll need javascript for that), but that’s another issue. I know I need a viewmodel to access all the tables, but I’m unclear as to how the viewmodel should be structured correctly.
Also, can the ShiftController update the ShiftActivity table directly or do I need to transfer the data somehow to the ShiftAcitivityController when the form is submitted? Either way, can someone point me to an example? Thank you… Any help is greatly appreciated.

Related

Entity Framework Core Navigation Properties and Joins, Correct Pattern

I'm struggling to understand the best way to implement some database relationships in EF Core.
Specifically, it involves the navigation properties, where you make a collection in the parent and an object in the child.
Looking at the MS docs here
Relationships, navigation properties, and foreign keys
there is the typical use case presented of a parent child relationship
public class Course
{
public int CourseID { get; set; }
public string Title { get; set; }
public int Credits { get; set; }
public int DepartmentID { get; set; }
public virtual Department Department { get; set; }
}
public class Department
{
public Department()
{
this.Courses = new HashSet<Course>();
}
public int DepartmentID { get; set; }
public string Name { get; set; }
public decimal Budget { get; set; }
public DateTime StartDate { get; set; }
public virtual ICollection<Course> Courses { get; set; }
}
Now this is fine for the above use case.
However, I am working on a specification system for process recipes. There are lots of machines, materials, areas, buildings and other things involved.
One of the tables in the database is "Unit", as in unit of measurement - that is kg, m, cm, etc.
This table is used as a lookup in many tables in the database, at least 20.
As such, if I've understood the recommended approach, I would end up with
pubic class Unit
{
public Guid Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Recipes> Recipes{ get; set; }
public virtual ICollection<Coll2> Coll2{ get; set; }
public virtual ICollection<Coll3> Coll2{ get; set; }
public virtual ICollection<Coll4> Coll2{ get; set; }
public virtual ICollection<Coll5> Coll2{ get; set; }
public virtual ICollection<Coll..n> Coll..n{ get; set; }
}
This applies not just for unit, but also for quite a few other generic lookup items, such as a warehouse. There are many entities that use a link to the warehouse.
What is the correct approach when using this kind of lookup?
I'm sorry if things aren't clear, hopefully they are.

Alter primary key with Entity Framework

First of all ASP.NET and MVC 4 are very new to me (+- one month) and sorry if its a bad question.
I've got two classes "Turma" and "Curso"
public class Turma
{
[Key]
public int idCurso { get; set; }
public string RefTurma { get; set; }
public Curso Curso { get; set; }
public string NomeCurso { get; set; }
}
and
public class Curso
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int idArtigoAT { get; set; }
public string ConteudoPrograma { get; set; }
public virtual ICollection<Turma> Turmas { get; set; }
}
After this I started a migration and updated the database. So far so good, but then problems.
Due to new information the primary key type should be varchar(18). I've tried to change but so far without success.
Any ideia or solution???
No, what you want is an 'Id' property and an 'MyCustomUniqueName' property. this custom property, should be and unique index in database. this is the best design for this situation IMHO.

EF 5.0 Code First mapping issues between 3 entities

I've got 2 entities:
public class School
{
public int Id { get; set; }
...
public virtual ICollection<Seminar> Seminars { get; set; }
}
public class Seminar
{
public int Id { get; set; }
...
public virtual ICollection<School> Schools { get; set; }
public virtual ICollection<Price> Prices { get; set; } // wrong??
}
public class Price
{
public int Id { get; set; }
public decimal Value { get; set; }
public virtual School School { get; set; }
public virtual Seminar Seminar { get; set; }
}
How to map "Price" property for getting something like this:
var priceOfSomeSeminar = someSchool.Seminars[0].Price
Is it possible? So I think I need help with the Fluent API modelBuilder relationship establishment...
Well, ICollection doesn't have an indexer, so you can't use array syntax with it. You can, however, convert it to an IEnumerable and then convert that to a List, which can then be indexed.
But no, you are using the correct semantics, so this should just work. No need to work with the fluent api.
I think you have an error though, Price should not have a School member. There is no direct relationship between price and school.

MVC EF Code First one to one relationship error

I want to have a list of stands (at a trade show) and a list of exhibitors.
The list of stands is separate to the list of exhibitors - however, once registered, I want the exhibitor to be able to book a stand.
When they select/book a stand - I would like to then be able to have a list the stands in my view, and also show the associated exhibitor who has booked it.
Likewise, I would like to list in another view, the exhibitors, and also which stand they have booked.
So I'm trying to setup a one to one relationship (using EF CodeFirst).
However, when trying to add a controller for either the Stand or the Exhibitor, I get the following error:
My models are:
public class Stand
{
public int StandID { get; set; }
public string Description { get; set; }
public bool Booked { get; set; }
public int ExhibitorID { get; set; }
public virtual Exhibitor Exhibitor { get; set; }
}
public class Exhibitor
{
public int ExhibitorID { get; set; }
public string Company { get; set; }
public int StandID { get; set; }
public virtual Stand Stand { get; set; }
}
I'm certain it's something to do with the "Virtual" part of the models.
Can anyone please help point out what should be updated, to allow the connection?
Thank you,
Mark
EF doesn't know which entity is the principal (parent) and which is the dependent (child). You need to declare a foreign key on the item that entity that should come first. You can do this with an annotation or a fluent mapping.
Annotation
Add the following namespace:
using System.ComponentModel.DataAnnotations.Schema;
Annotate your Stand class with the following annotation:
public class Stand
{
[ForeignKey("Exhibitor")]
public int StandID { get; set; }
public string Description { get; set; }
public bool Booked { get; set; }
public int ExhibitorID { get; set; }
public virtual Exhibitor Exhibitor { get; set; }
}
Fluent Mapping
Override your OnModelCreating method in your DbContext class to include:
modelBuilder.Entity<Stand>()
.HasOptional(s => s.Exhibitor)
.WithRequired(e => e.Stand);
The model you have created is not possible to work with relational databases. The Stand needs an ExibitorId while Exibitor need a StandId. The cyclic relationship does not allow you to insert any rows to either tables.
Assuming an Exibitor may have more than one Stand and converting the relationship to one-to-many is one option.
public class Stand
{
public int StandID { get; set; }
public string Description { get; set; }
public bool Booked { get; set; }
public int? ExhibitorID { get; set; }
public virtual Exhibitor Exhibitor { get; set; }
}
public class Exhibitor
{
public int ExhibitorID { get; set; }
public string Company { get; set; }
public virtual ICollection<Stand> Stands { get; set; }
}
Or you can use shared primary key mapping to make the relationship one-to-one. Where Stand is the principal entity. The Exibitor will use the StandID as its PK.
public class Stand
{
public int StandID { get; set; }
public string Description { get; set; }
public bool Booked { get; set; }
public virtual Exhibitor Exhibitor { get; set; }
}
public class Exhibitor
{
public int ExhibitorID { get; set; }
public string Company { get; set; }
public virtual Stand Stand { get; set; }
}
Using the Fluent API to configure the relationship.
modelBuilder.Entity<Exibitor>().HasRequired(e => e.Stand)
.WithOptional(s => s.Exibitor);

What is the most efficient way to submit and save a form with several ICollection items?

I am having users fill out a form that requires a number of 'educational background' pieces of data:
public class EducationalBackground
{
public int EducationalBackgroundID { get; set; }
public string UniversityOrCollege { get; set; }
public string AreaOfStudy { get; set; }
public string Degree { get; set; }
public int YearReceived { get; set; }
public virtual Application Application { get; set; }
}
Here is the model for the full Application:
public class Application
{
public int ApplicationID { get; set; }
public Profile BasicInfoGatheredFromProfile { get; set; }
public virtual ICollection<EducationalBackground> EducationalBackground { get; set; }
public bool WillingToTravel { get; set; }
}
I am working on making a page where users can fill out the full application and it will render a partial view that allows them to add an "educational background" piece of data up to however many they have.
What would be the most efficient way to allow users to add in indefinite number of "education background" pieces of information in this application?
What I am thinking: I will need a ViewModel to allow for the IColleciton of EducationalBackground when I POST the form. Is jQuery the cleanest way to add additional fields for 'educational background'?
An example POST action would be appreciated in addition to any information one is able to provide.

Resources