I have the following code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
namespace MyTestWebsite.Models
{
public class Page
{
public int Id { get; set; }
public int AuthorUserId { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string Content { get; set; }
public bool Hidden { get; set; }
}
public class PageState
{
public int Id { get; set; }
public string Type { get; set; }
}
public class MyTestWebsiteDBContext : DbContext
{
public DbSet<Page> Pages { get; set; }
public DbSet<PageState> PageStates { get; set; }
}
}
I went to create a controller for Page and I found the model structure.. no problems.
This is, I need another model called PageState and my model list does not show this second model.
Is it usual to have a heck load of models.... regardless of them being linked in some way?
Do I just add a model on its own called PageState?
Is it usual to have a heck load of models
Yes, they are called view models. Each view should have a specific view model. It's perfectly normal to have many view models if you have many views. A view model could aggregate one or more of your EF domain models.
Related
To make data-layer be aware of my domain classes, I've added a reference between the two class libraries, HMSContext (i.e., data-layer) and Hms.Entities (i.e., domain-classes).
Following is code from HMS.Entities:
namespace HMS.Entities
{
class Accomodation
{
public int ID { get; set; }
public int AccomodationPackageID { get; set; }
public AccomodationPackage AccomodationPackage { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
}
Code from HMSContext.cs:
using System.Data.Entity;
namespace HMS.Data
{
public class HMSContext : DbContext
{
public DbSet<Accomodation> Accomodations { get; set; }
}
}
I've added a reference between these two .dlls. A snapshot showing this is attached here. For some reason, HRMContext.cs is not reading HMS.Entities despite added reference. Am I missing anything? Can someone please shed light on this. Thanks in advance.
You are using using System.Data.Entity; where it is not related to your project structure. So add HMS.Entities too.
Any time you have such a problem, try using the full namespace and check if it is correct or not.
Note that you also have refactoring capabilities too. You can use ( Ctrl + . ) and Visual Studio helps you to use the correct namespace.
Your code has to be like this:
using System.Data.Entity;
using HMS.Entities;
namespace HMS.Data
{
public class HMSContext : DbContext
{
public DbSet<Accomodation> Accomodations { get; set; }
}
}
And for the Entity class you should use public keyword:
namespace HMS.Entities
{
public class Accomodation
{
public int ID { get; set; }
public int AccomodationPackageID { get; set; }
public AccomodationPackage AccomodationPackage { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
}
I’m creating a web API in MVC. The database is (thus far) simple, only three tables. I am unable to join them, though. I’ve tried three different methods for joining tables in the controller, and all return the same error, which is:
Cannot covert type (something*) to
‘Systems.Collections.Generic.IEnumerables< SalesDbApi.Sample>’ An
explicate conversion exists. Are you missing a cast?
(* The "something" portion is different depending on how the join occurs but the rest of the message remains the same, so I am assuming it is the relevant part.)
I’m guessing there is something wrong with how I have setup my Entity Relationships in Linq, because if I don’t do a join and just do a select all from Sample I get the following JSON back:
{"SampleId":10,"Barcode":"863760","CreatedAt":"2016-01-25T00:00:00","CreatedBy":10,"StatusID":3,"User":null,"Status":null}
User and Status aren’t fields in the Sample table. They are the names of the tables I am trying to link with, so I wouldn't expect them to appear.
Any idea on what I've done wrong?
Here are my three models:
Users.cs
namespace SalesDbApi
{
using System;
using System.Collections.Generic;
public partial class User
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public User()
{
this.Samples = new HashSet<Sample>();
}
public int UserId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Sample> Samples { get; set; }
}
}
Statuses.cs
namespace SalesDbApi
{
using System;
using System.Collections.Generic;
public partial class Status
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Status()
{
this.Samples = new HashSet<Sample>();
}
public int StatusId { get; set; }
public string Status1 { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Sample> Samples { get; set; }
}
}
Samples.cs
namespace SalesDbApi
{
using System;
using System.Collections.Generic;
public partial class Sample
{
public int SampleId { get; set; }
public string Barcode { get; set; }
public Nullable<System.DateTime> CreatedAt { get; set; }
public int CreatedBy { get; set; }
public int StatusID { get; set; }
public virtual User User { get; set; }
public virtual Status Status { get; set; }
}
}
Here’s the code from the controller
SalesUsersController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using SalesDbApi;
namespace SalesProject.Controllers
{
public class SalesUsersController : ApiController
{
webapitestdbEntities1 db = new webapitestdbEntities1();
public IEnumerable<Sample> Get()
{
{
db.Configuration.ProxyCreationEnabled = false;
var query = from x in db.Samples
join q in db.Users
on x.CreatedBy equals q.UserId
select q.FirstName;
return query.ToList();
}
}
i think table Samples or table users not a data in database. besause linq can't accommodate table with no data.
so when implementing entity framework code first in mvc, do we separate the view restrictions from view model? this is because for database first the model is generated(so i see the reason to separate it to view model but how about code first?)
The next questions i would ask is it ok to separate view model to another folder? since by default asp.net is MVC there is no view model inside
Model <--- what is this model call? data model? domain model? business model?
public class Student
{
public int ID { get; set; }
[StringLength(250)]
public string LastName { get; set; }
public string FirstMidName { get; set; }
public DateTime EnrollmentDate { get; set; }
}
View Model
public class Student
{
public int ID { get; set; }
[MaxLength(250)]
[Required]
public string LastName { get; set; }
[Required]
public string FirstMidName { get; set; }
[Required]
public DateTime EnrollmentDate { get; set; }
}
Your model that Used in mvc views is viewmodel.
your model that persist in database is domain model.
Your domain model may has some properties that you don't need use it in your client.
Your Service layer must return Dto (data transfer object) to your client and you can map dto to viewmodel .
First Question:
You should use partial class and metadata to seperate , just like below:
[MetadataType(typeof(StudentMD))]
public partial class Student
{
public class StudentMD
{
public int ID { get; set; }
[MaxLength(250)]
[Required]
public string LastName { get; set; }
[Required]
public string FirstMidName { get; set; }
[Required]
public DateTime EnrollmentDate { get; set; }
}
}
Second Question:
It's OK to add a folder name "View Model"
I did it in my project too!
I am using Visual Studio 2012, MVC 4, and Razor (CSHTML). I created Person.Person table in a test database. I wanted to have my model PersonModels.cs use this table so I created the following 2 classes.
public class Person
{
[Key]
public int BusinessEntityID { get; set; }
public string PersonType { get; set; }
public string Title { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public string Suffix { get; set; }
public int EmailPromotion { get; set; }
[XmlAttribute(DataType = "string")]
public string AdditionalContactInfo { get; set; }
[XmlAttribute(DataType = "string")]
public string Demographics { get; set; }
public string rowguid { get; set; }
public DateTime ModifiedDate { get; set; }
}
public class PersonDbContext : DbContext
{
public DbSet<Person> person { get; set; }
}
I thought that it would pick the Person.Person table since the class name was Person even though I had not included the schema. However, upon running the application and doing an insert I checked the Person.Person table but the row wasn't there. It created dbo.People table and inserted the row there! I double checked because I thought I might be drunk but I did not write People anywhere!
I read about reverse poco but I'd like to understand how this works more than making it work.
Edit: It worked! Please find the code I used attached:
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
namespace client_site.Models
{
[Table("Person", Schema = "Person")]
public class TestModel
{
[Key]
public int ID { get; set; }
}
public class DefaultConnectionX : DbContext
{
public DbSet<TestModel> test { get; set; }
}
}
dbo is the default database schema. If you want to create the table in the people schema you have to add an attribute
[Table("Person", Schema = "Person")]
When I try to add a 'MOVIES" controller, it errors: "There was an error generating 'MvcMovieSF.Models.MovieDBContext. Try rebuilding your project."
I have rebuilt the project and it continues to error. Thanks in advance!
namespace MvcMovieSF.Models
{
public class Movie
{
public int ID { get; set; }
public string Title { get; set; }
public DateTime ReleaseDate { get; set; }
public string Genre { get; set; }
public decimal Price { get; set; }
}
public class MovieDBContext : DbContext
{
public DbSet Movies { get; set; }
}
}
JUST NOTICED: I'm not sitting at my own computer and I noticed SQLExpress services were not started; I don't have permission on this computer to start the service. Could that be the reason?
Adding a controller also modifies your context class. If you have implemented partial class to add some business rules into your context, the framework cannot successfully edit your partial class to find the correct points for its own insertions.
Stupid, though, removing the business rules might help. After creating your controller, you can put them back.
(at least, this worked for me, 10 minutes ago...)
Edit:
The Context class might be partially implemented like this:
public partial class MyDatabaseEntities : DbContext
{
public override int SaveChanges() { ... }
#region Some Business Rules Here
...
#endregion
}
Here, if you try to add a new controller, you will fail with the error: "There was an error generating 'MyDatabaseEntities'. Try rebuilding your project."
And rebuilding will not help at all...
My solution is:
Remove these business rules like this, of course, keep them in a safe place, as you will probably need them afterwards:
public partial class MyDatabaseEntities : DbContext
{
public override int SaveChanges() { ... }
}
Create your controller. You should be successful this time.
Remove the codes that are added by the framework from your context class:
public partial class MyDatabaseEntities : DbContext
{
public override int SaveChanges() { ... }
public DbSet<MyModelClass> MyModelClass { get; set; } // remove this line
}
Put the business rules back.
Hope this helps.
I had the same problem while adding new controller in ASP.NET MVC 4, I solved the problem by moving the Database.SetInitializer(new SomeDataContextInitializer()); from the constructor of the DBContext to Application_Start method in Global.asax.cs. Hope it helps.
#Bolt Thunder put me on the right track. In my case, the DbContext class was modified to have IDbSet for testing, which made it happen. Changed that - problem solved.
my project name was MVC and i had this class
public class download
{
public int download_id { get; set; }
public int download_category_id { get; set; }
public string download_name { get; set; }
public int download_size { get; set; }
public string download_description { get; set; }
public string download_path { get; set; }
public download_category download_category { get; set; }
}
public class download_category
{
public int download_category_id { get; set; }
public string download_category_name { get; set; }
}
public class DownloadDbContext : DbContext
{
public DbSet<download> downloads { get; set; }
public DbSet<download_category> download_categorys { get; set; }
}
and i got similar error when scaffolding(there was an error generating try rebuilding your project).
i am using visual studio 2012 version 11.0.50727.1 RTMREL and reference to entity as ...\EntityFramework.5.0.0\lib\net45\EntityFramework.dll
first i divide class into three classes (three seperate *.cs files) and also use DataAnnotations in download and download_category classes to use [key] for id columns and problem solved.
my classes were as below in Models folder :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MVC.Models;
using System.ComponentModel.DataAnnotations;
namespace MVC.Models
{
public class Download
{
[Key]
public int download_id { get; set; }
public int download_category_id { get; set; }
public string download_name { get; set; }
public int download_size { get; set; }
public string download_description { get; set; }
public string download_path { get; set; }
public Download_category download_category { get; set; }
}
}
and
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
namespace MVC.Models
{
public class Download_category
{
[Key]
public int download_category_id { get; set; }
public string download_category_name { get; set; }
}
}
and
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
namespace MVC.Models
{
public class DownloadDbContext:DbContext
{
public DbSet<Download> downloads { get; set; }
public DbSet<Download_category> download_categorys { get; set; }
}
}
I had the same problem as Susan. In my case specifying the model type for the DbSet (public DbSet<Movie> Movies ) in the context class fixed the problem.
I am using VS 2012 and i added the Entity Framework 5.0 package to the solution.