I'm learning EF using Code First and I'm having a lot of trouble getting my relationships to build correctly.
A Simple Employee
public class Employee
{
[Key]
public int EmployeeId { get; set; }
public String FirstName { get; set; }
public String LastName { get; set; }
}
A Simple Project
public class Project
{
[Key]
public int ProjectId { get; set; }
public String ProjectNumber { get; set; }
}
The time spent on the project
public class Time
{
[Key]
public int TimeId { get; set; }
public int EmployeeID { get; set; }
public String ProjectID { get; set; }
public long? TimeSpent { get; set; }
public virtual Employee Employee { get; set; }
public virtual Project Project { get; set; }
}
I'm trying to join Employee to Time on EmployeeID and join Project to Time on ProjectID and I just don't understand how EF determines relationships. I'm trying to use Data Annotations to define the relationships. I've tried using the ForeignKey annotation to define the relationships but that has not worked either.
What I have will run, but on the Project table, a new field named Project_ProjectID is created and if I try to run a query in VS I get an error saying that the column Time_TimeID is invalid (which it is). What am I doing wrong?
You shouldn't need DataAnnotations as conventions will work for you in this case
Try the following
public class Time
{
[Key]
public int TimeId { get; set; }
public int EmployeeID { get; set; }
public int ProjectID { get; set; } //<< Changed type from string
public long? TimeSpent { get; set; }
public virtual Employee Employee { get; set; }
public virtual Project Project { get; set; }
}
public class Employee
{
[Key]
public int EmployeeId { get; set; }
public String FirstName { get; set; }
public String LastName { get; set; }
// Set up the other side of the relationship
public virtual ICollection<Time> Times { get; set; } // << Added
}
public class Project
{
[Key]
public int ProjectId { get; set; }
public String ProjectNumber { get; set; }
// Set up the other side of the relationship
public virtual ICollection<Time> Times { get; set; } // << Added
}
This article may help
http://msdn.microsoft.com/en-gb/data/jj679962.aspx
Related
Hi I am working on entity framework core. I have user table and user may be part of multiple projects. And user for each project has to enter time sheet data. For example below is my user table.
public class User
{
[Key]
public string Id { get; set; }
public string name { get; set; }
public string emailId { get; set; }
}
Below is my project table.
public class Project
{
[Key]
public string Id { get; set; }
public string Name { get; set; }
public string userId { get; set; }
}
Here User may belong to multiple projects. Now for each project user has to enter timesheet data. Below is timesheet table.
public class TimeSheetData
{
[Key]
public string id { get; set; }
public string project_id { get; set; }
public string hours_logged { get; set; }
}
I have to define this in entity framework core. One user may be part of multiple projects and user needs to enter data to timesheet for each project. How can I define relationship with respect to above table?
In user table Do I need to add something like Public List<Project> Projects? Also In Project table Public List<Timesheet> Timesheets something I have to define here. Can some one help me to understand this? Any help would be greatly appreciated. Thanks
Assuming you will be changing string to int ids, does something below work?
public class User
{
public User()
{
this.Projects = new HashSet<Project>();
}
[Key]
public int Id { get; set; }
public string name { get; set; }
public string emailId { get; set; }
public virtual ICollection<Project> Projects { get; set;}
}
public class Project
{
public Project()
{
this.TimeSheetData = new HashSet<TimeSheetData>();
}
[Key]
public int Id { get; set; }
public string Name { get; set; }
public int userId { get; set; }
[ForeignKey("userId")]
public virtual User User {get; set; }
public virtual ICollection<TimeSheetData> TimeSheetData { get; set;}
}
public class TimeSheetData
{
[Key]
public int id { get; set; }
public int project_id { get; set; }
[ForeignKey("project_id")]
public virtual Project Project {get; set; }
public string hours_logged { get; set; }
}
I have created an MVC using Entity framework and I've encountered a situation which I don't know how to resolve.
I'm using the EF auto joins and relations (all my table models were created automatically by EF) .
Now for the problem - I have a table of customers, which has two(relavent) fields - personID and employerID . Only one of them contains data , the other will be null (a customer is either a person , or an employer) . When I try to include employer model in the result set, I'm getting thrown (without any message , when I debug I see that the content has data but the employeer is sometimes NULL) I'm also not sure about how the design should look like. This is my code :
Customer:
public partial class Customer
{
public Customer()
{
Account = new HashSet<Account>();
}
public long Id { get; set; }
public int? PersonId { get; set; }
public int Type { get; set; }
public int? EmployerId { get; set; }
public Employer Employer { get; set; }
public ICollection<Account> Account { get; set; }
}
Employer:
public partial class Employer
{
public Employer()
{
Customer = new HashSet<Customer>();
}
public int Id { get; set; }
public string Name { get; set; }
public int? IdType { get; set; }
public ICollection<Customer> Customer { get; set; }
}
Person:
public partial class Person
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int Sex { get; set; }
public DateTime? BirthDate { get; set; }
public int IdType { get; set; }
}
Now when I'm running in my repository:
var collectionBeforePaging = _context.Customer
Everything works, but Employer is NULL. If I use :
var collectionBeforePaging = _context.Customer.Include(a => a.Employer)
Then the project fails .
How can I make this joins?
Please define ForeignKey for Customer
public int? EmployerId { get; set; }
[ForeignKey(nameof(EmployerId))]
public virtual Employer Employer { get; set; }
What version of EF you use? I think you missing something like that :
In Employer :
[ForeignKey("EmployerId")]
[InverseProperty("Customers")]
public virtual Employer Employer { get; set; }
public int? EmployerId { get; set; }
In Customer :
[InverseProperty("Employer")]
public virtual ICollection<Customer> Customers { get; set; }
It can also be done in the Dbontext object
My data class is
public class Data
{
public int Id { get; set; }
public int LeagueId { get; set; }
public League League { get; set; }
public int HomeTeamId { get; set; }
public virtual Team HomeTeam { get; set; }
public int AwayTeamId { get; set; }
public virtual Team AwayTeam { get; set; }
}
and my team class is
public class Team
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Data> Datas { get; set; }
}
which generates an extra foreign key FK_dbo.Data_dbo.Teams_Team_Id and also and extra column in my Data table.
So my first question is, how that foreign-key was created there?
Can i have two one to many relationships that target at the same table with entity framework?
I need to set both the HomeTeamId and the AwayTeamId in the Data table as one to many relationship
Try:
public class Data
{
public int Id { get; set; }
public int LeagueId { get; set; }
[ForeignKey("LeagueId")] /* Add explicit foreign key data annotations */
public League League { get; set; }
public int HomeTeamId { get; set; }
[ForeignKey("HomeTeamId")]
public virtual Team HomeTeam { get; set; }
public int AwayTeamId { get; set; }
[ForeignKey("AwayTeamId")]
public virtual Team AwayTeam { get; set; }
}
public class Team
{
public Team()
{
this.HomeTeamData = new HashSet<Data>();
this.AwayTeamData = new HashSet<Data>();
}
public int Id { get; set; }
public string Name { get; set; }
[InverseProperty("HomeTeam")]
public virtual ICollection<Data> HomeTeamData { get; set; }
[InverseProperty("AwayTeam")]
public virtual ICollection<Data> AwayTeamData { get; set; }
}
Let me know if this helps.
I suspect you may be hitting the limit of Entity's ability to figure out what you want. You may need to consider using some Entity Annotations to instruct Entity on what you want it to actually do.
I am a VB.NET programmer, but I am trying to learn C# and MVC in my spare time. I am using ASP.NET MVC 5.1.0.0 and I am trying to do code-First database creation in a local instance of SQL Server.
I was able to get the first database table to update in the database when I ran Update-Database from within the IDE, but when I added a second table that has a PK/FK relationship with the first, I am getting a red line under [ForeignKey] which reads
Does not contain a constructor that takes 1 arguments
I have been searching all over and not getting anywhere. Any suggestions or help would be appreciated. By the way, the first table is a PK/FK relationship to the AspNetUsers table.
public class BuildDatabase : IdentityUser
{
public virtual Companies Companies { get; set; }
public virtual NotaryProfile NotaryProfile { get; set; }
}
public class Companies
{
[Key]
[Column("CompanyID")] // Did this as the database will reflect TableName_ColumnName instead.
public int CompanyID { get; set; }
public string CompanyName { get; set; }
public bool IsActive { get; set; }
public bool IsNotary { get; set; }
public virtual ICollection<NotaryProfile> NotaryProfile { get; set; }
}
public class NotaryProfile
{
[Key]
public int NotaryID { get; set; }
public string NamePrefix { get; set; }
public string FirstName { get; set; }
public string MiddleInitial { get; set; }
public string LastName { get; set; }
public string NameSuffix { get; set; }
public bool IsActive { get; set; }
public int DefaultState { get; set; }
public int DefaultCounty { get; set; }
public bool IsSigningAgent { get; set; }
public bool HasABond { get; set; }
public decimal BondAmount { get; set; }
public bool HasEandO { get; set; }
public decimal EandOAmount { get; set; }
public bool ElectronicNotarizationsAllowed { get; set; }
public string ElectronicTechnologyUsed { get; set; }
public string ComissionNumber { get; set; }
public DateTime CommissionIssued { get; set; }
public DateTime CommssionOriginal { get; set; }
public DateTime CommissionExpires { get; set; }
public DateTime CommissionFiledOn { get; set; }
public string SOSAuditNumber { get; set; }
public string CommissionDesc { get; set; }
[Foreignkey("CompanyID")] // Companies.CompanyID = PK
public int CompanyID { get; set; } // PK/FK relationship.
public Companies Companies { get; set; } // Reference to Companies table above.
}
public class SchemaDBContext : IdentityDbContext<BuildDatabase>
{
public SchemaDBContext()
: base("DefaultConnection"){}
public DbSet<Companies> Companies { get; set; }
public DbSet<NotaryProfile> NotaryProfile { get; set; }
}
One of your classes (probably NotaryProfile) needs to reference another object (the foreign key relationship) but there is no constructor in that class that accepts an argument to establish that relationship, e.g.:
public NotaryProfile(int companyId) {
this.companyId = companyId;
}
BTW, a better way to establish that relationship is to use the actual class type rather than the ID, as in:
public class NotaryProfile {
...
public Company Company { get; set; }
// Instead of this:
// public int CompanyID { get; set; } // PK/FK relationship.
...
}
See also:
C# “does not contain a constructor that takes '1' arguments”
Does not contain a constructor that takes 2 arguments
Am building tender board Application am getting some confusing in how structure my model using >> entity-framework in >> MVC4
Here the descriptions:
In my simple membership Role Table , I have:
(Admin,Tender,Provider,Member)
Administration: he have right to change normal user role from “Member” to “Provider and prove winner bidder after tender organization approved.
Suppliers: Normal users will be assigning as “member” and will be activated by Administration to be provider and then they can bid any projects they want.
Projects: created by Tender Organization Users every project has many requirements
Requirement: each one related to project.
Tenders: Here my problem actually Tender are “Ministries in country and have to be set in system” but each ministry obvious have many users “Manager, let say 5 in each” who will vote for supplier.Mangers can vote to only those suppliers which are laid under the same ministry.
Do I miss others tables?
Also I don’t really know how to structure all the tables with relations and also with (UserprofileTbale, and Role Table):
Here my try, help me on that.
My DBContext:
public class ProjectContext : DbContext
{
public ProjectContext()
: base("OTMSProjects")
{
}
public DbSet<ProjectEntry> Entries { get; set; }
public DbSet<Requiernments> RequiernmentEntries { get; set; }
public DbSet<Supplier> Suppliers { get; set; }
public DbSet<Tender> Tenders { get; set; }
public DbSet<UserProfile> UserProfiles { get; set; }
//public DbSet<UserRoles> UserRoles { get; set; } // do I have to set this too?
}}
My tables:
public class ProjectEntry
{
[Key]
public int ID { get; set; }
[Required]
public string ProjectName { get; set; }
public string Description { get; set; }
public string Statue {get; set; }
public string UplodedFiles { get; set; }
public string Budget { get; set; }
public string EstimateTime { get; set; }
public string Criterias { get; set; }
public DateTime? DueDate { get; set; }
// Relations with others tables
public virtual Tender Tender { get; set; }// every project have only one tender
public virtual ICollection<Supplier> Suppliers { get; set; } // every project have one or more supplier
public virtual ICollection<Requiernments> Requirements { get; set; }
}
........
public class Requiernments
{
[Key]
public int RequiernmentId { get; set; }
public int ID { get; set; }
public string RequiernmentName { get; set; }
public string RequiernmentType { get; set; }
public string RequiernmentPrioritet { get; set; }
public float RequiernmenWhight { get; set; }
public string ProviderAnswer { get; set; }
public string ProviderComments{ get; set; }
public virtual ProjectEntry Projects { get; set; }
}
........
public class Supplier
{
[Key]
public int SupplierId { get; set; }
public int ID { get; set; }
public int SupplierName { get; set; }
public int SupplierCat { get; set; }
public virtual ICollection<ProjectEntry> Projects { get; set; }
}
......
public class Tender
{
[Key]
public int TenderId { get; set; }
public string TenderName { get; set; }
public string TenderMinstry{ get; set; }
public int ID { get; set; }//link to project
public int UserId { get; set; } //this links to the userid in the UserProfiles table
public virtual ICollection<ProjectEntry> Projects { get; set; }
//public virtual ICollection<UserProfile> Userprofile { get; set; }
public virtual UserProfile UserProfile { get; set; }
}
My membership table in my AccountModel created by defualt in Mvc4 ( I only add the RoleTable :
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public string EmailAddress { get; set; }
public ICollection<UserRoles> UserRoles { get; set; }
}
[Table("webpages_Roles")]
public class UserRoles
{
[Key]
public int RoleId { get; set; }
public string RoleName { get; set; }
[ForeignKey("UserId")]
public ICollection<UserProfile> UserProfiles { get; set; }
}
Am not sure also about how to link the Userprofile with Tender Table and supplier Table?
Not sure what you are missed or not. but as per database creation you must follow your business logic and normalization rules.
Some of my suggestions are here:
1. ProjectEntry
here you should create a Status Table separately and gives its reference key as StatusID into the ProjectEntry table.
Requirement
you should create Requirement Priority and Type tables are separately.
Add separate table for provider question and answers. I hope you need to store more than one question answers for single requirement.
Supplier
Add Separate Table for Supplier category
Tender
Create Tender Ministry table separately and give its reference to the tender table.
you should make a table for Uploaded files as Documents. It should contains ID, ProjectId, Documentname, DocumentType, DocumentShortDescription, uplodatedDateTime fields.