I've created an MVC 3 Razor application that manages Projects, and should manage Sections within those Projects.
So, I've made a model Projects.cs, controller ProjectsController, and got myself a Projects.sdf data table. Works just fine
Then I've added same for Sections, but Sections should have a field named projectID (made it of course) that is connected (joined) with ID in Projects.sdf; also, I need it to be able to be sorted by projectID, and from a DropDown
For example: Using DropDown to alter the table data. If lets say I select project1 from Project list, I want the list to show all Sections within that Project along with CRUD.
I've tried several things but none worked so far, I know how to do this in regular application but not in MVC so I beg for some assistance. Also tried to add DropDown in Sections view and getting it to populate from Project model data, but no good at all.
So I need help on how to do this :(
Please, and thank you.
Addition
Project has many Sections, and yes I'm using EF, but as I said not too experienced with it.
as for data context
this is Project
namespace MyProject.Models
{
public class Projects
{
public int ID { get; set; }
public string projectName { get; set; }
public string shortDesc { get; set; }
}
public class ProjectsDBContext : DbContext
{
public DbSet<Projects> Projects { get; set; }
}
}
this is Section
namespace MyProject.Models
{
public class Sections
{
public int ID { get; set; }
public int projectID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
public class SectionsDBContext : DbContext
{
public DbSet<Sections> Sections { get; set; }
}
}
Addition 2
So I made a model named MyProjectModels.cs
namespace MyProject.Models
{
public class Project
{
public int ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
public class Section
{
public int ID { get; set; }
public int projectID { {get; set;}
public string Name { get; set; }
public string Description { get; set;}
}
}
So basically I'm kinda figuring it out. Please let me know if this is ok for models or do I need to put them in separate files? Also, How should i declare context from this point, a hint would be enough :)
Thank you
This is the way I have done it. It displays properly but i have NO idea how to utilize it, for example to show different values in a table...
<select id="select1" name="select1">
#foreach (var item in Model.Enrollments)
{
<option value=#Html.DisplayFor(modelItem => item.Course.Title)>#Html.DisplayFor(modelItem => item.Course.Title)</option>
}
</select>
by different values in table i meant, when i select different enrollment in this case. i would like to show different values in table.
Do you really need to have different dbcontexts? If it is one sdf file then I'm guessing not and your dbcontext should look like
namespace MyProject.Models
{
public class DatabaseContext: DbContext
{
public DbSet<Projects> Projects { get; set; }
public DbSet<Sections> Sections{ get; set; }
}
}
then in your projects model you would have a property for sections
namespace MyProject.Models
{
public class Projects
{
public int ID { get; set; }
public string projectName { get; set; }
public string shortDesc { get; set; }
public Sections section { get; set; }
}
}
and your sections would just need an id field
namespace MyProject.Models
{
public class Sections
{
public int ID { get; set; }
public int projectID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
}
As long as your sections class has a primary key field called ID or the id property flagged as the primary key then EF will make the logical leap that Projects has a foreign key of section in the table structure. your projects model will then have access to the section object. Biggest hurdle I had with EF was overthinking the database side of things.
For the dropdown list here is the way I have done it
public class ChangeUserNameViewModel
{
public ChangeUserNameViewModel()
{
var user = User.GetAllButBuiltIn();
Users = new SelectList(user, "UserName", "UserName");
}
public User User
{
get;
set;
}
[DisplayName("User Name")]
public SelectList Users
{
get;
set;
}
public string UserName
{
get;
set;
}
}
then in the view I reference the viewmodel
#model ChangeUserNameViewModel
#Html.DropDownList("UserName", Model.Users, "Choose")
the first parameter is the name of the drop down in the html. the second the select list to populate it and the third the selected value. I'm sure there are better ways to do it. For example you could have an IList in your model and then do a foreach loop in your view. It all depends on what works best in your case.
Related
I've been trying to figure out how to do the following (although my research did not help): I have the these three classes:
public abstract class Classifier
{
public int ClassifierId { get; set; }
public string ClassifierName { get; set; }
public DateTime DateAdded { get; set; }
}
public class ManualClassifier : Classifier
{
public int ManualClassifierId { get; set; }
public string user_name { get; set; }
public string userName { get; set; }
public string firstName { get; set; }
public string lastName { get; set; }
public string email { get; set; }
public string password { get; set; }
}
public class ToolClassifier : Classifier
{
public int ToolId { get; set; }
public string ToolName { get; set; }
}
Both the ManualClassifier and ToolClassifer inherit from Classifier. I'm using EF Core to map this to a database but the question is the following: I've already searched a bit and I must make use of a descriminator which basically is an implicitly created column that will say the type of, in this case, classifier. So far so good. The issue arises when I have a property called ManualClassifierId as well as a ToolId. I want this two properties to map to the ClassifierId property. So in the table representing the entity Classifier, the ClassifierId property will either be the ManualClassifierId or the ToolId.
How can I achieve this mapping? Also, this solution would mean that both child classes would both have empty fileds in the tables (due to inheriting the three properties from the Classifier class). Is there a better solution? Perhaps just erase the Id's from both child classes a let them inherit the parent one?
Thank you in advance!
To use the same column name in both classes, you can add a Column attribute to both properties. Then they will both use that column name in the database. See ColumnAttribute(String).
Use it like this:
public class ManualClassifier : Classifier
{
[Column(Name="ClassifierId")]
public int ManualClassifierId { get; set; }
...........
}
Do the same with ToolId.
I have a sqlite database which has some tables and columns like the following:
int Id
text Name
text Comment
...
And my object in my project looks like this:
Public Class Entry {
public int Id { get; set; }
public String Name { get; set; }
public String Comment { get; set; }
public String Additional { get; set; }
}
This can happen, because my programm need to handle different versions of the database.
EF Core now trys to access the Additional field of the database but returns an error that it cannot find the field. (Expected behaviour)
Now my question is, if there is a way to ignore this error and return a default value for the property?
I could bypass the error by making the properties nullable. But i don't want to check each property with .HasValue() before accessing it. Because the real database has 50+ columns in the table.
https://www.entityframeworktutorial.net/code-first/notmapped-dataannotations-attribute-in-code-first.aspx
Put NotMapped as an attribute on the Additional field:
using System.ComponentModel.DataAnnotations.Schema;
Public Class Entry {
public int Id { get; set; }
public String Name { get; set; }
public String Comment { get; set; }
[NotMapped]
public String Additional { get; set; }
}
This tells EF that the field is not a column in the database.
I would advise you to split your domain object from that persisted dto object. That way you can have different dtos with different mappings. Now you can instantiate your domain object with your dto and decide inside your domain object what values are the correct default values.
public class Entry
{
public int Id { get; set; }
public string Name { get; set; }
public string Comment { get; set; }
public string Additional { get; set; }
}
public class EntryDtoV1
{
public int Id { get; set; }
public string Name { get; set; }
public string Comment { get; set; }
}
public class EntryDtoV2
{
public int Id { get; set; }
public string Name { get; set; }
public string Comment { get; set; }
public string Additional { get; set; }
}
Now you only need to create some kind of factory that creates the correct repository depending on what database version you query.
I am having a weird issue with my project. I have 2 models in my project and they are called Job and Jobs. Originally when I started the project it created the tables in SQL as Jobs and Jobs1. I am confused as to why it called the tables these names. When I deleted the tables in SQL and recreated them to add changes I named them Job and Jobs. When I run the project and try to retrieve the data it is telling me it cannot find dbo.Jobs1. I do not have anything in my code that would make entity framework create these tables in the first place. Also my AspNet _Migration table does not exist anymore. I deleted it due to changes and the system usually puts a new one back but it doesn't appear to do this either. Not important to me unless someone can tell me that it will break the system if not there or that the problem I am having is related. I have done a search in the project for dbo.Jobs1 and just Jobs1 and nothing comes up. Could someone direct me as to where to correct this and maybe why it created these tables in that fashion in the first place. Thank you.
These are the models of question in my project:
public class Job
{
public Job()
{
SubJobs = new List<Jobs>();
}
[Key]
public string TopLvlJob { get; set; }
public string Description { get; set; }
public string ExtDescription { get; set; }
public string PartNumber { get; set; }
public string Drawing { get; set; }
public bool UpgradeAvailable { get; set; }
public virtual IEnumerable<Jobs> SubJobs { get; set; }
}
}
public class Jobs
{
public Jobs()
{
Parts = new List<MaterialRequired>();
}
[Key]
public string JobNumber { get; set; }
public string Drawing { get; set; }
public string PartNumber { get; set; }
public string Description { get; set; }
public string ExtDescription { get; set; }
public string TopLvlJob { get; set; }
public bool IsViewable { get; set; }
public virtual IEnumerable<MaterialRequired> Parts { get; set; }
}
I have four MVC model layer domain classes.
namespace MvcMobile.Models.BusinessObject
{
public class Speaker
{
public int SpeakerID { get; set; }
public string SpeakerName { get; set; }
}
public class Tag
{
public int TagID { get; set; }
public string TagName { get; set; }
}
public class Seminar
{
public string Seminar_Code { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string Room { get; set; }
}
public class Seminar_Detail
{
public string Seminar_Code { get; set; }
public int SpeakerID { get; set; }
public int TagID { get; set; }
public string DateAndTime { get; set; }
}
}
I would like to make CRUD operation by using these classes. So I create two VeiwModel Classes.
namespace MvcMobile.ViewModel
{
public class Seminar_Root_ViewModel
{
public Seminar_Subsidiary_ViewModel Seminars { get; set; }
public List<Speaker> Speakers { get; set; }
public List<Tag> Tags { get; set; }
}
public class Seminar_Subsidiary_ViewModel
{
public Seminar Seminar { get; set; }
public List<Seminar_Detail> Seminar_Detail { get; set; }
}
}
For Controller layer, I consider that I will use Seminar_Root_ViewModel to make the whole CRUD operation processes.
What I would like to ask is that Is this proper way or correct way?
If you have more elegant way to make model layer and ViewModel layer, Please let me get suggestion.
Every suggestion will be appreciated.
[updated]
Let's assume that I make master-Detail form design.
Speaker and Tag are just look-up tables for dropdownlist or some controls like that.
Seminar is Master Data and Seminar_Detail will be Item Grid Data.
So As for this scenario, all of this classes are needed for this program.
Please let me know if my thinking is wrong.
The only thing I can see is if you are not going to re-use your Seminar_Subsidiary_ViewModel view model you could skip it.
If you are going to need those two properties Seminar and Seminar_Detail on another view or ajax call, it's perfectly fine to have that kind of separation.
Personally I'm not a huge fan of _ on class name, but that have nothing to do with the question.
Consider this Poco:
public class User
{
public int Id { get; set; }
public string Username { get; set; }
public string Fullname { get; set; }
}
Now i want to implement a follow technique where a user may follow other users so basically its self Many to Many relationship
problem is i don't know how exactly i can achieve this in Entity Framework Code-First ?
I thought of a linker Table :
public class UserFollow
{
public int Id { get; set; }
public int Follower { get; set; }
public int Following { get; set; }
public DateTime FollowDate { get; set; }
}
i want to be able to get All Followers and Following from every User Object?
This is quite simple using EF code-first as you only need the User POCO:
public class User
{
public int Id { get; set; }
public string Username { get; set; }
public string Fullname { get; set; }
public ICollection<User> FollowedUsers { get; set; }
}
The collection means that a User is related to other users.
PS: I noted you added a timestamp in your solution example. To achieve that you should still add the collection changing the generic type to whatever suits your needs.
Hope it helps.