I am using EF Migrations with MVC 5 - however I'm getting what I think/thought was/is a pretty common error, but the common solutions I've seen, I've already got:
The property 'companyId' cannot be configured as a navigation property.The property must be a valid entity type and the property should have a non-abstract getter and setter. For collection properties the type must implement ICollection where T is a valid entity type.
From looking around my code looks correct, and worked prior to enable-migrations and update-database to see whether the test data in my system gets wiped before I put this change live. Within the ASN model I've added a string property of testAsn to see whether this gets added as a column to the database.
I am unsure if this error is relating to the ASN or the Contacts table/model, but they both have the same implementation.
Have I misunderstood regarding the use of navigational properties? Any help would be greatly appreciated.
Models
[Table("Company")]
public class Company
{
[Key]
public int companyId { get; set; }
[Required(ErrorMessage="Company name required.")]
[StringLength(100)]
public string name { get; set; }
[Required(ErrorMessage = "Telephone required.")]
public string telephone { get; set; }
[Required(ErrorMessage="Registration Number required.")]
[StringLength(30)]
public string regNumber { get; set; }
// navigation properties of the models that belong to the company
public virtual IList<Asn> asns { get; set; }
public virtual IList<Contact> contacts { get; set; }
}
[Table("Asn")]
public class Asn
{
[Key]
public int asnId { get; set; }
public int companyId { get; set; }
[ForeignKey("companyId")]
// property I'm adding to test whether migrations is working
public string testAsn { get; set; }
// *******************************
// as pointed out in the correct answer, the property below
// this comment should be above testAsn
// *******************************
public virtual Company company { get; set; }
[Required] // always has value
public bool userBehalf { get; set; }
[Required] // always has value
public bool confirmAssignment { get; set; }
[Required(ErrorMessage="Prefix required.")]
public string prefixAnnounced { get; set; }
[Required(ErrorMessage="Pending Ticket ID required.")]
public string pendingTicket { get; set; }
[DataType(DataType.MultilineText)]
public string comments { get; set; }
public bool asNumType { get; set; }
public string reason { get; set; }
}
[Table("Contact")]
public class Contact
{
[Key]
public int contactId { get; set; }
public int companyId { get; set; }
[ForeignKey("companyId")]
public virtual Company company { get; set; }
[StringLength(100, MinimumLength=3)]
[Required(ErrorMessage="Contact name required.")]
public string name { get; set; }
[Required(ErrorMessage="Telephone required.")]
[StringLength(30, MinimumLength=11)]
public string telephone { get; set; }
[Required]
[RegularExpression(#"^([a-zA-Z0-9_\-\.]+)#((\[[0-9]{1,3}" +
#"\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\" +
#".)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$",
ErrorMessage = "Email is not valid.")]
public string email { get; set; }
[Required(ErrorMessage = "Contact type required.")]
public string type { get; set; }
}
You have misplaced the ForeignKey attribute in the Asn class. Instead of putting it on the company property, it's on the testAsn property.
Related
I have 2 model classes:
Department.cs
public class Department
{
public string DepartmentId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
[ForeignKey("FacultyId")]
public IList<Faculty> Faculties{ get; set; }
[ForeignKey("FacultyId")]
public Faculty HOD { get; set; }
}
Faculty.cs
public class Faculty
{
public string FacultyId { get; set; }
public string FacultyName { get; set; }
public FacultyStatus FacultyStatus { get; set; }
public Designation Designation { get; set; }
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
[DataType(DataType.PhoneNumber)]
public string PhoneNumber { get; set; }
public string Address { get; set; }
public int Experience { get; set; }
public string Qualifications { get; set; }
public string Description { get; set; }
public Department Department{ get; set; }
}
I am having trouble determining how to set the HOD for the department. What I thought of was, making the HOD column a foreign key, but I don't know how good or useful that would be.
I referred to this link to learn, but I am unable to apply the same.
I'm getting an error:
Unable to determine the relationship represented by navigation 'Department.Faculties' of type 'ICollection'. Either manually configure the relationship, or ignore this property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.
I am trying to create code first approach a user table which have different foreign keys,but I it gives me error with this message:
"The ForeignKeyAttribute on property 'discount_id' on type 'EFNetflixAssignment.User' is not valid. The foreign key name 'Discounts' was not found on the dependent type 'EFNetflixAssignment.Discount'. The Name value should be a comma separated list of foreign key property names."
Here is my code for the user table
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Required]
public virtual int Id { get; set; }
[Required]
public virtual bool Status { get; set; }
[Required]
[MaxLength(255)]
public virtual string Email { get; set; }
[Required]
[MaxLength(255)]
public virtual string Password { get; set; }
[Required]
public virtual List<Payment_type> Payment_Types { get; set; }
[Required]
public virtual bool Activated { get; set; }
[Required]
[ForeignKey("Discounts")]
public virtual List<Discount> discount_id { get; set; }
}
And here is the discount code
public class Discount
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Required]
public virtual int Id { get; set; }
[Required]
[MaxLength(255)]
public virtual string discount_type { get; set; }
[Required]
public virtual decimal discount_amount { get; set; }
}
Can somebody help me solve this issue?
The ForeignKey-Attribute won't work like this.
If you don't care about the name of the foreign key in the database, then you don't need this attribute. EF will automatically create a foreign key for the navigation properties.
If you want to specify the name of this key, then you need another property in the user class, that holds the foreign key and then you can connect these 2 properties in 2 possible ways:
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Required]
public virtual int Id { get; set; }
[Required]
public virtual bool Status { get; set; }
[Required]
[MaxLength(255)]
public virtual string Email { get; set; }
[Required]
[MaxLength(255)]
public virtual string Password { get; set; }
[Required]
public virtual List<Payment_type> Payment_Types { get; set; }
[Required]
public virtual bool Activated { get; set; }
[Required]
[ForeignKey("Discounts")]
public List<int> Discount_Ids { get; set; }
[Required]
public virtual List<Discount> Discounts { get; set; }
Or like this:
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Required]
public virtual int Id { get; set; }
[Required]
public virtual bool Status { get; set; }
[Required]
[MaxLength(255)]
public virtual string Email { get; set; }
[Required]
[MaxLength(255)]
public virtual string Password { get; set; }
[Required]
public virtual List<Payment_type> Payment_Types { get; set; }
[Required]
public virtual bool Activated { get; set; }
[Required]
public List<int> Discount_Ids { get; set; }
[Required]
[ForeignKey("Discount_Ids")]
public virtual List<Discount> Discounts { get; set; }
This is because whenever you want to set a specific name for a foreign key using Data Annotations you need to add a property for that key and connect it with the navigation property.
But be aware of the fact, that on your database the foreign key will be set in the discount table, because in a 1-to-many relationship the table on the many-side always takes the primary key of the 1-side as the foreign key for the relationship.
Hope this solves your issue, let me know if you have any further questions :)
I have two tables where I want to implement a 1-1 relationship.I run into a issue described in this post:
EntityFramework : Invalid column name *_ID1
I tried to implement the solution,to add the Foreign Key attribute and I run into another issue:
Multiplicity is not valid in Role 'Account_Companies_Target' in relationship 'Account_Companies'. Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be '*'.
These are the classes:
public class Account
{
[Key]
public Guid Id { get; set; }
public string CompanyName { get; set; }
public long CNP { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public long PhoneNumber { get; set; }
public string Address { get; set; }
[Required]
public string UserName { get; set; }
[Required(ErrorMessage = "Password is Required.")]
public string Password { get; set; }
public DateTime CreatedOn { get; set; }
[NotMapped]
[Required(ErrorMessage = "Confirmation Password is Required")]
[Compare("Password", ErrorMessage = "Password Must Match")]
public string ConfirmPassword { get; set; }
[Required]
public AccountType AccountType { get; set; }
public int CUI { get; set; }
[ForeignKey("Id")]
public virtual Company Companies { get; set; }
}
public class Company
{
[Key]
public long CUI { get; set; }
public Guid Id { get; set; }
public string CompanyName { get; set; }
public string Simbol { get; set; }
public int SharesCount { get; set; }
public decimal SharePrice { get; set; }
public virtual Account Account { get; set; }
}
and this is the OnModelCreating overide:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Account>()
.HasOptional(account => account.Companies)
.WithRequired(company => company.Account);
}
If Account.CUI, the foreign key property, is not a key, then the relationship is 1:many, not 1:1. And EF6 only allows an entity to have one key.
This question already has answers here:
Understanding ForeignKey attribute in entity framework code first
(3 answers)
Closed 1 year ago.
I have an issue in regards to creating a database from code first in entity framework. I have the following three classes 1 Person, 2 PersonAddress, 3 PersonEmploymentHistory as shown below.
namespace DataAccess.Models
{
[Table("Profile")]
public class Person
{
[Key]
public int UserId { get; set; }
[Required(ErrorMessage = "Firstname is required")]
public string PersonFirstName { get; set; }
[Required(ErrorMessage = "Surname is required")]
public string PersonSurname { get; set; }
[Required(ErrorMessage = "Email is required")]
[DataType(DataType.EmailAddress)]
public string PersonEmail { get; set; }
public int Age { get; set; }
[Required(ErrorMessage = "Contact Number required")]
public Int64 PersonNumber { get; set; }
public bool IsActive { get; set; }
[ForeignKey("AddressDetails")]
public int AddressId { get; set; }
public virtual PersonAddress AddressDetails { get; set; }
[ForeignKey("EmploymentHistory")]
public int EmployerId { get; set; }
public virtual PersonEmploymentHistory EmploymentHistory { get; set; }
}
}
PersonAddress Class
namespace DataAccess.Models
{
[Table("AddressDetails")]
public class PersonAddress
{
[Key]
public int AddressId { get; set; }
[ForeignKey("UserId")]
public int UserId { get; set; }
[Required(ErrorMessage = "Address Line 1 required")]
public string AddressLine1 { get; set; }
[Required(ErrorMessage = "Address Line 2 required")]
public string AddressLine2 { get; set; }
[Required(ErrorMessage = "Postcode required")]
[DataType(DataType.PostalCode)]
public string PostCode { get; set; }
}
}
PersonEmploymentHistory
namespace DataAccess.Models
{
[Table("EmploymentHistory")]
public class PersonEmploymentHistory
{
[Key]
public int EmployerId { get; set; }
public string EmployerName { get; set; }
public decimal EmployeeSalary { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public string ReasonForLeaving { get; set; }
[ForeignKey("UserId")]
public int UserId { get; set; }
}
}
And this is my Context class
public class Context : DbContext
{
public Context()
: base("DefaultConnection")
{
Database.SetInitializer<Context>(new CreateDatabaseIfNotExists<Context>());
}
public DbSet<Person> Person { get; set; }
public DbSet<PersonAddress> PersonAddress { get; set; }
public DbSet<PersonEmploymentHistory> PersonEmployment { get; set; }
}
Now I have followed tutorials when creating foreign keys etc but when I run my project and try to insert data into the person table I get the following error
The property 'UserId' cannot be configured as a navigation property. The property must be a valid entity type and the property should have a non-abstract getter and setter. For collection properties the type must implement ICollection where T is a valid entity type.
I am learning code first also. I am using the fluent API so I am not as experienced with annotations. I think the way you are doing your foreign keys is wrong. I think they should look like:
public int UserId { get; set; }
[ForeignKey("UserId")]
public virtual Person User{ get; set; }
The difference is you have an variable of the type for the FK and annotate that. You can also look up the fluent API.
see http://www.codeproject.com/Articles/319366/EF-Code-First-Add-a-Foreign-Key-relationship
I have had the same problem when developing and relating several tables, if you use FirstCode, I recommend using the following structure:
In Class "PersonAddress"
public long UserId{ get; set; }
[ForeignKey("UserId")]
public Person Person { get; set; }
For the table where you relate use the foreign key pointing or below the object.
Not used that:
[ForeignKey("UserId")]
public int UserId { get; set; }
you will do the same with the other tables that you are going to relate.
[ForeignKey("UserId")]
public virtual Person User{ get; set; }
[ForeignKey("User")]
public int UserId { get; set; }
you should use it like this. I also have the same problem I have solved this problem like this.
In the ForeignKey you need to add the class reference. Change to:
[ForeignKey("Person")]
public int UserId { get; set; }
public virtual Person User{ get; set; }
I need to bind some relations in Entity Framework Code First but I don't know how to. I searched deeply, I tried a lot of ways but still without luck. I think I need to use the fluent API.
Scenario
Organizations has many Notes.
Projects has many Notes.
Notes has one Organization or Project.
The idea is to bind every entity (Organization or Project) to only one column in Note entity: SourceKey.
Organization
public class Organization
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid ID { get; set; }
[Required(ErrorMessage = "A name is required.")]
public string Name { get; set; }
public virtual ICollection<Project> Projects { get; set; }
public virtual ICollection<Note> Notes { get; set; }
}
Project
public class Project
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid ID { get; set; }
[Required(ErrorMessage = "An organization is required.")]
[Display(Name = "Organization")]
public Guid OrganizationID { get; set; }
[Required(ErrorMessage = "A name is required.")]
public string Name { get; set; }
public virtual Organization Organization { get; set; }
public virtual ICollection<Note> Notes { get; set; }
}
Note
public class Note
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid ID { get; set; }
public Guid SourceKey { get; set; }
[Required(ErrorMessage = "A title is required.")]
public string Title { get; set; }
[Column(TypeName = "ntext")]
public string Value { get; set; }
public string Tags { get; set; }
}
So an example of data can be:
Organizations
7846ac27-d490-4483-8f0b-975a11333dea, Google
Projects
3446ac27-d490-4323-8121-921a11333dac, Search
7846ac27-8497-5683-213b-933a11233abc, Maps
Notes
1236ac27-d490-4323-8121-921a11333dac, 7846ac27-d490-4483-8f0b-975a11333dea, A note for Google organization
2346ac27-d490-4323-8121-921a11335aab, 7846ac27-d490-4483-8f0b-975a11333dea, Another note for Google organization
3456ac27-d490-4323-8121-921a11331bcc, 7846ac27-8497-5683-213b-933a11233abc, Just a note for Maps project
BTW
I don't need to navigate from Notes (up) to Organization or Project. If I have an Organization or Project, I will need to navigate (down) to Notes.
As mentioned above, if you don't require navigation properties from notes, you can omit them.
If you then included two fields on the Note class to use for foreign key associations:
public class Note
{
// Code
public Guid OrganizationId { get; set; }
public Guid ProjectId { get; set; }
}
I assume most notes won't belong to both an Organisation, and a Project (although they can).
You should be able to configure your mapping using the fluent API like this:
modelBuilder.Entity<Organization>()
.HasMany(o => o.Notes) // Many Notes
.WithOptional() // No navigation property on Notes
.HasForeignKey(n => n.OrganizationId ); // Use OrganizationId as a foreign key
modelBuilder.Entity<Project>()
.HasMany(o => o.Notes)
.WithOptional()
.HasForeignKey(n => n.ProjectId);
You can define the Note entity without navigation properties,
public class Note
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid ID { get; set; }
public Guid SourceKey { get; set; }
[Required(ErrorMessage = "A title is required.")]
public string Title { get; set; }
[Column(TypeName = "ntext")]
public string Value { get; set; }
public string Tags { get; set; }
public int OrganizationId { get; set; }
public int ProjectId { get; set; }
}
If you don't need navigation properties, you can define it simply using the class below:
public class Note
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid NoteID { get; set; }
public Guid SourceKey { get; set; }
[Required(ErrorMessage = "A title is required.")]
public string Title { get; set; }
[Column(TypeName = "ntext")]
public string Value { get; set; }
public string Tags { get; set; }
public Guid OrganizationId { get; set; }
public Guid ProjectId { get; set; }
}
Note OrganizationId and ProjectId are of type Guid.
I think that the use of one column (SourceKey) for multiple foreign keys is not possible. It throws you an error. I was pretty sure that was possible but maybe I'm confused with the MyISAM tables in MySQL. I will use the foreign keys columns in the Note model as Chris suggest. Thanks to everybody.