EF 6 - TPC - Many-To-Many Relationship - asp.net-mvc

I'm having trouble with my code-first approach to Entity Framework (6) in a project. I effectively have a database that I am attempting to write code that will cause Entity Framework to replicate. I've gotten close so far, but not 100%. The first issue is many-to-many relationship:
I have a base class called Consumer and it has just basic properties:
public abstract class Consumer
{
public Guid ID { get; set; }
[DataType(DataType.DateTime)]
public DateTime CreateDate { get; set; }
[DataType(DataType.DateTime)]
public DateTime? LastModDate { get; set; }
public int RecordStatus { get; set; }
}
I then want to use inheritance for the subsequent classes:
public class Entity : Consumer
{
[DisplayName("Entity Name")]
public string EntityName { get; set; }
[DisplayName("Phone Number"]
public string PhoneNumber { get; set; }
[DisplayName("Doing Business As"]
public string DBA { get; set; }
}
In my context class, I successfully map all of the properties to the table:
modelBuilder.Entity<Entity>().Map(m =>
{
m.MapInheritedProperties();
m.ToTable("Entity");
});
I continued this design with other classes (contacts for example):
public class Contact : Consumer
{
[DisplayName("First Name")]
public string FirstName { get; set; }
[DisplayName("Last Name"]
public string LastName { get; set; }
}
Now, obviously, a contact could be related to more than one Entity and an Entity could be related to more than one Contact. How would I code this? Only thing I could think of was to create a related class like so:
public class RelatedContact
{
public Guid ID { get; set;}
public Guid ContactID { get; set; }
public virtual Contact Contact { get; set; }
public Consumer Parent { get; set; }
public virtual Consumer Parent { get; set; }
public Guid RelationshipTypeID { get; set; }
public virtual RelationshipType RelationshipType { get; set; }
}
Then after creating the related class, I was assuming I needed to go update my Entity class like so:
public class Entity : Consumer
{
[DisplayName("Entity Name")]
public string EntityName { get; set; }
[DisplayName("Phone Number"]
public string PhoneNumber { get; set; }
[DisplayName("Doing Business As"]
public string DBA { get; set; }
public virtual ICollection<Contact> Contacts { get; set; }
}
Then, I would update my DbContext to map the many relationship, but I don't know the correct syntax or if this is even the correct way to approach this. I am trying to get the following tables to output:
<<Entity>>
ID uniqueidentifier,
CreateDate datetime,
LastModDate datetime,
RecordStatus int,
EntityName varchar(250),
PhoneNumber varchar(100),
DBA varchar(250)
<<Contact>>
ID uniqueidentifier,
CreateDate datetime,
LastModDate datetime,
RecordStatus int,
FirstName varchar(100),
LastName varchar(100)
<<RelatedContact>>
ID uniqueidentifier,
ContactID uniqueidentifier,
ParentID uniqueidentifier,
RelationshipTypeID uniqueidentifier
So, any suggestions? Am I at least headed in the right direction?

To create a many-to-many relationship, you need to use second approach. Just add navigation collection to your Entity and Contact classes. And EF will create linking table for you and track links.
public class Entity : Consumer
{
... your props
public virtual ICollection<Contact> Contacts { get; set; }
}
public class Contact : Consumer
{
... your props
public virtual ICollection<Entity> Entities { get; set; }
}

Related

ASP.NET MVC EF 6: define a lookup table/model

i am trying to define a database model in code-first to see and display which user is assigned as a specialist for the record data.
I have a very simple model for the user:
public class User
{
public int ID { get; set; }
public string userName { get; set; }
public string firstName { get; set; }
public string lastName { get; set; }
....
}
Next I have defined two (simple) models which define the data that can be edited by the user and the specialist should be assigned to using a dropdownlist:
public class Order
{
public int ID { get; set; }
public string orderNumber { get; set; }
public int specialistID { get; set; }
public virtual User specialist{ get; set; }
}
public class Part
{
public int ID { get; set; }
public string partNumber { get; set; }
public string description { get; set; }
public int specialistID { get; set; }
public virtual User specialist{ get; set; }
}
What kind of relation between the models can be used without having a navigation property for each table in the User model?
Do I need to use additional tables to define the relationship: User.Id-Order.specialistID and the relationship: User.Id-Part.specialistID ?
Is there a smarter way out-of-the-box by Entity Framework?
Many thanks for your answers.
Pascal
By default when you add forign-key constraint to the many-to-one table the Entity Framework add virtual property to the entity class and virtual ICollection to the User.

ASP.NET MVC & EF5 - Create column type datetime2, Key property

Question 1.
I have created a database in code-first.
[Column(TypeName="datetime2")]
public DateTime RegistDate { get; set; }
In this way, the table is not created.
modelBuilder.Entity<Test>().Property(f => f.RegistDate).HasColumnType("datetime2");
(In OnModelCreating method)
I can be resolved by using Fluent API.
To create a column format datetime2, is there a way only a Fluent API?
Question 2.
I have a domain model as follows.
User Entity Class
public class User
{
public Guid UserId { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public string UserEmail { get; set; }
public DateTime JoinDate { get; set; }
public DateTime LoginDate { get; set; }
public virtual ICollection<UsersInRole> UsersInRoles { get; set; }
}
Role Entity Class
public class Role
{
public Guid RoleId { get; set; }
public string RoleName { get; set; }
public DateTime CreateDate { get; set; }
public virtual ICollection<UsersInRole> UsersInRoles { get; set; }
}
UsersInRole Entity Class
public class UsersInRole
{
public Guid UserId { get; set; }
public Guid RoleId { get; set; }
public DateTime SetDate { get; set; }
[ForeignKey("UserId")]
public User User { get; set; }
[ForeignKey("RoleId")]
public Role Role { get; set; }
}
This build, the following error will occur
One or more validation errors were detected during model generation:
\tSystem.Data.Entity.Edm.EdmEntityType: : EntityType 'UsersInRole' has no key defined. Define the key for this EntityType.
\tSystem.Data.Entity.Edm.EdmEntitySet: EntityType: EntitySet 'UsersInRoles' is based on type 'UsersInRole' that has no keys defined.
I do not want to add another property Id.
Also, I can not use the [Key] UserId, to RoleId.
There are no other solutions?

asp.net MVC 4 EntityType: EntitySet has no keys defined

I am a MVC newbie so go easy on me please.
I am getting two errors when I try to add a migration. They are as follows:
EntityType 'Icon' has no key defined. Define the key for this EntityType.
EntityType: EntitySet 'Icons' is based on type 'Icon' that has no keys defined.
I am including the Icon inside another model, like so:
public class Icon
{
public string IconName { get; set; }
public string IconColor { get; set; }
public int BackgroundXPos { get; set; }
public int BackgroundYPos { get; set; }
public string IconColorHover { get; set; }
public int BackgroundHoverXPos { get; set; }
public int BackgroundHoverYPos { get; set; }
}
public class GalleryThumbnail : CSSBoxModel
{
[DisplayName("Thumbnail Image Outline Color")]
public string ThumbnailImageOutlineColor { get; set; }
[DisplayName("Thumbnail Menu Font")]
public CSSFont ThumbnailMenuFont { get; set; }
[DisplayName("Thumbnail Icon Color")]
public Icon ThumbnailIconColor { get; set; }
}
How is this Address class below any different which is working:
public class Address
{
public String Adress1 { get; set; }
public String Adress2 { get; set; }
public String Adress3 { get; set; }
public String City { get; set; }
public String County { get; set; }
public String State { get; set; }
public String Zip { get; set; }
public String Country { get; set; }
}
[Table("UserProfile")] //Could be PP empolyee, Subscriber or Subscriber's customer
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public bool? Gender { get; set; }
public Address Address { get; set; } //billing address
public Address ShipAddress { get; set; }
}
I did not add a key in either my Icon or Address class because I have no intention of storing specific data in my DB. They are merely to be used inside other classes. So wy is one neededing an ID and the other is not?
I have not created public DbSet Icons { get; set; } in my DB Context either.
Also can you tell me what it is called when you use a class inside another ( or instance of class inside a class as in these examples ) ?
Much appreciated!
Since the address entity has no key defined it the Entity Framework assumes it's a complex property, and your UserProfile table will be rendered with columns named Addres_Address1, Address_Address2, Address_Address3, Address_City, and so on...
Even though you haven't declared an EntitySetIcons DbSet on your context class, it's still being added implicitly because one of your other classes somewhere has an ICollection or IEnumerable property defined.
More info on Code Conventions here:
http://msdn.microsoft.com/en-us/data/jj679962.aspx
So, either decorate the collections as NotMapped like #Kamyar said or simply remove the references from any class already declared as a DbSet.
you can use [NotMapped] attribute in System.ComponentModel.DataAnnotations.Schema namespace in EntityFramework.dll:
using System.ComponentModel.DataAnnotations.Schema;
...
[NotMapped]
public Address Address { get; set; } //billing address
[NotMapped]
public Address ShipAddress { get; set; }
Regarding the naming, AFAIK these are called public properties as well.

MVC 4 Entity Framework - Foreign Key to UserProfile

I've created a standard MVC 4 application using the built in account controllers/models/views. I've now tried to add another controller but I want to create a foreign key relationship to an existing user, but im getting the error message:
The ForeignKeyAttribute on property 'CreatedBy' on type 'MVC4App.Models.ListingModel' is not valid. The foreign key name 'UserId' was not found on the dependent type 'MVC4App.Models.ListingModel'. The Name value should be a comma separated list of foreign key property names.
The Listing Model Code is:
using System;
using System.ComponentModel.DataAnnotations.Schema;
namespace MVC4App.Models
{
public class ListingModel
{
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Location { get; set; }
public string Instrument { get; set; }
public string Genres { get; set; }
public string Description { get; set; }
[ForeignKey("UserId")]
public virtual UserProfile CreatedBy { get; set; }
public DateTime CreatedOn { get; set; }
}
}
What am I missing here? Or is there a better way I should be doing this?
Also I'm assuming I can just add extra properties to the user profile such as an email address or a link to an avatar image later on in the project?
You have to add the UserId to your entity:
namespace MVC4App.Models
{
public class ListingModel
{
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Location { get; set; }
public string Instrument { get; set; }
public string Genres { get; set; }
public string Description { get; set; }
public int UserId {get; set;}
[ForeignKey("UserId")]
public virtual UserProfile CreatedBy { get; set; }
public DateTime CreatedOn { get; set; }
}
}

EF Code First Foreign Key's

I am working with the EF Code First library trying to work on an appointment scheduling app.
The model's I have are going to be a Client, Appointment, and AppointmentType...
Basically each Client can have a set of Appointments, and each Appointment can have a single AppointmentType...
The code is as follows:
public class Client
{
[ScaffoldColumn(false)]
public int ClientID { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
[EmailAddress]
[Required]
public string Email { get; set; }
[DataType("DateTime")]
public DateTime Birthday { get; set; }
[Required]
public string CellPhone { get; set; }
public string HomePhone { get; set; }
public string Notes { get; set; }
public virtual ICollection<Appointment> Appointments{ get; set; }
public string Name {
get{
return FirstName + " " + LastName;
}
}
public class Appointment
{
[ScaffoldColumn(false)]
public int AppointmentID { get; set; }
[ScaffoldColumn(false)]
public int ClientID { get; set; }
[ScaffoldColumn(false)]
public int AppointmentTypeID { get; set; }
[Required]
public DateTime AppointmentDate { get; set; }
public string Notes { get; set; }
public virtual AppointmentType AppointmentType { get; set; }
public virtual Client Client { get; set; }
}
public class AppointmentType
{
[ScaffoldColumn(false)]
public int AppointmentTypeID { get; set; }
[Required]
public string Name { get; set; }
public string Description { get; set; }
public virtual Appointment Appointment { get; set; }
}
Everything works well when I create an appointment type, and a client, but when I create an appointment I get the following error...
InnerException {"The INSERT statement conflicted with the FOREIGN KEY constraint \"Appointment_Client\". The conflict occurred in database \"Salon.Models.SalonContext\", table \"dbo.Clients\", column 'ClientID'.\r\nThe statement has been terminated."} System.Exception {System.Data.SqlClient.SqlException}
If more details are needed, please let me know...I am just trying to figure out if I am missing anything in the setup.
This is what happens when I debug on the post to create the Appointment...All the ID's are as 0 which is correct, but should the other fields not be null?? Or does it matter...Just not very familiar with how things should look this being my first EF Code First project...
According to your setup, one AppointmentType can only have one Appointment. This is a one-to-one mapping. In this case, you better move the AppointmentType into the Appointment entity. Otherwise, what I believe is more logical, an AppoitmentType can have many Appointments but one Appointment can have only one AppointmentType. Accordingly, you should have a virtual ICollection inside your AppointmentType entity.
public class AppointmentType
{
[ScaffoldColumn(false)]
public int AppointmentTypeID { get; set; }
[Required]
public string Name { get; set; }
public string Description { get; set; }
public virtual ICollection<Appointment> Appointments { get; set; }
}
I am not sure this is what's causing the problem but it could be. Sometimes mapping faults cause some weird exceptions to be thrown. Give it a try and let me know if your problem gets resolved.
By your constraints AppointmentType and Client cannot be null in Appointment. You can delete constraints or set correct objects in object properties. For example create Client and AppointmentType and then create Appointment for created Client with created AppointmentType

Resources