I want to create a model on MVC3, but instead of creating a model for a table, I want to create one for a view in my Database. I know that with models for tables, I need to specify primary keys when creating the model, if not i get some error messages. Since views do not have have primary/foreign keys, how do I go about creating models for View?
At any MVC application that works with EF you may have different models to create tables in db or conceptual model for view that doesn't create any tables.Table creation depends on what properties of which model classes you'll define in class that inherited from DbContext. Notice that any property that exists in this class and its relational classes will create table in db. So,to create models that will be used only at view, you can define models that don't have any relationship to other table creator models plus no definition at inherited DbContext class. Then you can use them as model or class to show data at the view.The controller and its related view should use the same model and no errors will be occurred.
public class datacontext : DbContext
{
public DbSet<Person> people { get; set;}
public DbSet<Address> address { get; set;}
}
public class Person
{
[Key]
public int ID { get; set;}
public String Name { get; set;}
}
public class Address
{
[Key]
public int ID { get; set;}
public Country country { get; set;}
public String Details { get; set;}
}
public class Country
{
[Key]
public int ID { get; set;}
public String Name { get; set;}
}
public class Work_Field//without any key definition
{
public String Title { get; set;}
public String Description { get; set;}
}
Here we have this tables : Person, Address, Country(Although it's not defined at datacontext class)
In this example, you can use Work_Field as view model perhaps with some DataAnnotations like [Required],... to force user don't leave parameter empty, and so more.
Related
I have this class
public class Teacher
{
public int Id{ get; set; }
public ICollection<Product> Products{ get; set; }
}
Below code is from the designer class generated by the EF migrations
modelBuilder.Entity("XYZ.Models.Entities.Product", b =>
{
b.HasOne("XYZ.Models.Entities.Teacher")
.WithMany("Courses")
.HasForeignKey("TeacherId");
});
I've checked my database, there is no such thing that shows where the Products IDs stored or anything, yet it works!
Where does that info get stored?
I have annotated some of my model classes' keys with [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
and added a migration.
When running Update-Database I keep getting following error message:
To change the IDENTITY property of a column, the column needs to be dropped and recreated.
I also tried to Update-Database with a complete new database, to no avail as the error is the same.
When changing the identity property in SQL Server Management Studio, I do not get such error but I would like to avoid a mix of code and DB first approach.
Is there a way to either
force the update to drop and recreate the column
or drop and recreate the table ?
EDIT1:
To answer a question from the comments. My model class before looked like:
public partial class MyModel
{
[Key]
public int Id { get; set; }
[MaxLength(70)]
public string Name { get; set; }
public string Description { get; set; }
...
}
This is my model class after adding the annotation:
public partial class MyModel
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[MaxLength(70)]
public string Name { get; set; }
public string Description { get; set; }
...
}
I was encountring an error when I try to add class to the database
DB.Trips.Add(trip);
I solved it by setting the navigation properties to null, but i never had to do that before and it worked just fine, so im wondering why is that, as it doesnt seem to me as a good approach and the problem might persist.
When I do the DB.SaveChanges(); I get an error. From the SQL profiler I found out that it is trying to insert a record into Countries table.
exec sp_executesql N'insert [dbo].[Countries](......
But Trips table doesn't even have Country property. There is a City property, which has Country. But why would it try to add that as well and how can I force it to insert only into Trips table ?
The data comes in via angular $http.post, is it possible its somehow related ?
Trip class city related attributes
public int CityOriginID { get; set; }
public int CityDestinationID { get; set; }
public virtual City CityDestination { get; set; }
public virtual City CityOrigin { get; set; }
City class
public partial class City
{
public int CityID { get; set; }
public string Name { get; set; }
public string CountryCode { get; set; }
public virtual Country Country { get; set; }
}
Thanks for any suggestions
Try adding a reference to your Trip entity in your City entity like
public virtual ICollection<Trip> Trips {get; set;}
to indicate your one-to-many relationship
I'm new to asp.net mvc and entity framework code first apporach, I'm not that keen on databases either. I apologise in advance for wrong terminology or the way I understand things.
Now to the question. I have the following models:
User Model
public class User
{
public int UserId { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public int RoleId { get; set; }
[ForeignKey("RoleId")]
public virtual IEnumerable<Role> Roles { get; set; }
}
Role Model
public class Role
{
public int RoleId { get; set; }
public string RoleName { get; set; }
}
What i eventually want is a way to use Ef codefirst approach with the fluent API to map the UserId and RoleId to a User_Role table with a one-to-many relation, a user can have multiple roles:
I assume that what s done in this question is the right approach, except that there the author used a many-to-many connection. I tried it that way but the part with u => u.users gives me an error(I assume thats because there is no users property in the model, so he answered his question but didn't update his question?)
My question: What is the exact fluent api code to let Ef generate this table for me?
Things I'm unsure about: (Feel free to ignore)
Is this the right approach of my problem?
Once i have the lookup table, is this still the right way to declare my navigational property so i can later use it like user.Roles and retrieve their roles?
where will be the RoleId in the User model be populated from, Roles table or User_Role?
Has having an ID in the lookup table any use?
Thanks in advance! I really appreciate your expertise.
First you should get rid of the RoleId property in the User model. Having that as a foreign key tells which single role a user has. Since a user can have many roles, the foreign key should not be in the user table but in the mapping table.
So what you have is a many-to-many relationship between users and roles, and Entity Framework can create the needed mapping table automatically without you having to configure anything.
If you simply have a Roles property in the User entity and a Users property in the Role entity, EF will figure out that you want a many-to-many between those two, and create a table with the primary keys of both entities as a combined primary key, which will be used to map users to roles.
When loading a User from the database you can then use the Roles navigation property to figure out which roles the user has, and you can load a Role to figure out which users are in that role.
The simplest way of making it work would be something like this:
public class Context : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Role> Roles { get; set; }
static Context()
{
Database.SetInitializer(new DropCreateDatabaseAlways<Context>());
}
public Context()
: base("Server=localhost;Initial Catalog=Test;Integrated Security=True;")
{
}
}
public class User
{
public int UserId { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public List<Role> Roles { get; set; }
}
public class Role
{
public int RoleId { get; set; }
public string RoleName { get; set; }
public List<User> Users { get; set; }
}
Running that code results in 3 tables like this:
I have DB that contains 3 tables - Actors, Films, Actors_Films. 2 of the tables have a many-to-many relationship (Actors and Films), which is modelled using a junction table (Actors_Films).
I'm using EF4 in a Silverlight app. I've created a EF model, and the edmx designer shows just my Ac tors and Films entities, but they each have a navigation property to the other entity (Actors has a navigation property of Films, and Films has a navigation property of Actors).
I've added a domain service, and built the project. Using Actors as an example I now want to add a view that contains a dataform that will let me cycle through Actors, and a datagrid that will show any films the currently selected actor has appeared in. However, in the Data source tab, I have a domain context containing 2 entities - Actors and Films. These 2 entities are only showing their actual columns, the navigation properties aren't appearing:
Actors
---ActorID
---ActorName
Films
---FilmID
---FilmTitle
Is this correct? I thought the navigation properties should show up.
My actual application is more complicated than this, but this is a simplified example just to focus on the actual issue.
Thanks
Mick
WCF Ria Services don't support Many To Many Relation. You must have association table on edmx. In order that Navigate properties appear on client you must add [Include] attribute to navigate property in apropriate metadata of Entity. The metadata usually generated when you create any DomainService. For example, we have relation many to many ContractPosition and OrderPosition:
//ContractPositionsService.metadata.cs
[MetadataTypeAttribute(typeof(ContractPosition.ContractPositionMetadata))]
public partial class ContractPosition
{
internal sealed class ContractPositionMetadata
{
public int ContractPositionId { get; set; }
[Include]
public EntityCollection<ContractToOrderLink> ContractToOrderLinks { get; set; }
...
}
//ContractToOrdersLinksService.metadata.cs
[MetadataTypeAttribute(typeof(ContractToOrderLink.ContractToOrderLinkMetadata))]
public partial class ContractToOrderLink
{
internal sealed class ContractToOrderLinkMetadata
{
[Include]
public ContractPosition ContractPosition { get; set; }
public int ContractPositionId { get; set; }
[Include]
public OrderPosition OrderPosition { get; set; }
public int OrderPositionId { get; set; }
}
}
//OrderPositionsService.metadata.cs
[MetadataTypeAttribute(typeof(OrderPosition.OrderPositionMetadata))]
public partial class OrderPosition
{
internal sealed class OrderPositionMetadata
{
public int OrderPositionId { get; set; }
[Include]
public EntityCollection<ContractToOrderLink> ContractToOrderLinks { get; set; }
...
}
}