Entity Framework 6 NOT recognizing a Foreign Key which exists - entity-framework-6

I have a table contacts which has two phones for primaryphone and secondaryphone. Both of these have fields primaryphonetypeid and secondaryphonetypeid. These two columns reference the same table phonetype. No matter what I do, EF will not recognize the secondaryphonetypeid as a foreign key. I have even removed the primaryphonetypeid from my code and killed its foreign key constraint and it still says the secondaryphonetypeid does not exist.
[Table("PhoneType", Schema = "lkp")]
public class PhoneTypeEntity
{
[Key]
[Required]
[Column("PhoneTypeId")]
public int PhoneTypeId { get; set; }
[Column("PhoneTypeName")]
public string PhoneTypeName { get; set; }
}
public class ContactEntity
{
[Key]
[Required]
[Column("ContactId")]
public int ContactId { get; set; }
[Column("AccountId")]
public int? AccountId { get; set; }
[ForeignKey("AccountId")]
public virtual AccountEntity Account { get; set; }
[Column("ContactTypeId")]
public int? ContactTypeId { get; set; }
[ForeignKey("ContactTypeId")]
public virtual ContactTypeEntity ContactType { get; set; }
[Column("FirstName")]
public string FirstName { get; set; }
[Column("LastName")]
public string LastName { get; set; }
[Column("EmailAddress")]
public string EmailAddress { get; set; }
[Column("PrimaryPhone")]
public string PrimaryPhone { get; set; }
[Column("PreferredContactMethodId")]
public int? PreferredContactMethodId { get; set; }
[ForeignKey("PreferredContactMethodId")]
public virtual PreferredContactMethodEntity PreferredContactMethod { get; set; }
[Column("AddressLine1")]
public string AddressLine1 { get; set; }
[Column("AddressLine2")]
public string AddressLine2 { get; set; }
[Column("PrimaryPhoneTypeId")]
public int? PrimaryPhoneTypeId { get; set; }
[ForeignKey("PrimaryPhoneTypeId")]
public virtual PhoneTypeEntity PrimaryPhoneType { get; set; }
[Column("SecondaryPhone")]
public string SecondaryPhone { get; set; }
[Column("SecondaryPhoneTypeId")]
public int? SecondayPhoneTypeId { get; set; }
[ForeignKey("SecondaryPhoneTypeId")]
public virtual PhoneTypeEntity SecondaryPhoneType { get; set; }
}
As you can see there are other foreign keys in this table and they all work fine.
Here is the table with the constraints. No matter what I have tried, it will not recognize SecondaryPhoneTypeId as a foreign key in entity framework.
CREATE TABLE [dbo].[Contact](
[ContactId] [int] IDENTITY(1,1) NOT NULL,
[AccountId] [int] NULL,
[ContactTypeId] [int] NOT NULL,
[PreferredContactMethodId] [int] NULL,
[FirstName] [nvarchar](50) NULL,
[LastName] [nvarchar](50) NULL,
[AddressLine1] [nvarchar](100) NULL,
[AddressLine2] [nvarchar](100) NULL,
[PrimaryPhone] [nvarchar](10) NULL,
[PrimaryPhoneTypeId] [int] NULL,
[SecondaryPhone] [nvarchar](10) NULL,
[SecondaryPhoneTypeId] [int] NULL,
[State] [nvarchar](5) NULL,
[EmailAddress] [nvarchar](100) NULL,
[PostalCode] [nvarchar](10) NULL,
[IsMilitary] [bit] NULL DEFAULT ((0)),
[City] [nvarchar](50) NULL,
CONSTRAINT [PK_ContactDetail] PRIMARY KEY CLUSTERED
(
[ContactId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Contact] WITH NOCHECK ADD CONSTRAINT [FK_Contact_Account] FOREIGN KEY([AccountId])
REFERENCES [dbo].[Account] ([AccountId])
NOT FOR REPLICATION
GO
ALTER TABLE [dbo].[Contact] NOCHECK CONSTRAINT [FK_Contact_Account]
GO
ALTER TABLE [dbo].[Contact] WITH CHECK ADD CONSTRAINT [FK_Contact_ContactType] FOREIGN KEY([ContactTypeId])
REFERENCES [lkp].[ContactType] ([ContactTypeId])
GO
ALTER TABLE [dbo].[Contact] CHECK CONSTRAINT [FK_Contact_ContactType]
GO
ALTER TABLE [dbo].[Contact] WITH NOCHECK ADD CONSTRAINT [FK_Contact_PreferredContactMethod] FOREIGN KEY([PreferredContactMethodId])
REFERENCES [lkp].[PreferredContactMethod] ([PreferredContactMethodId])
NOT FOR REPLICATION
GO
ALTER TABLE [dbo].[Contact] NOCHECK CONSTRAINT [FK_Contact_PreferredContactMethod]
GO
ALTER TABLE [dbo].[Contact] WITH NOCHECK ADD CONSTRAINT [FK_Contact_PrimaryPhoneTypeId] FOREIGN KEY([PrimaryPhoneTypeId])
REFERENCES [lkp].[PhoneType] ([PhoneTypeId])
NOT FOR REPLICATION
GO
ALTER TABLE [dbo].[Contact] NOCHECK CONSTRAINT [FK_Contact_PrimaryPhoneTypeId]
GO
ALTER TABLE [dbo].[Contact] WITH NOCHECK ADD CONSTRAINT [FK_Contact_SecondaryPhoneTypeId] FOREIGN KEY([SecondaryPhoneTypeId])
REFERENCES [lkp].[PhoneType] ([PhoneTypeId])
NOT FOR REPLICATION
GO
ALTER TABLE [dbo].[Contact] NOCHECK CONSTRAINT [FK_Contact_SecondaryPhoneTypeId]
GO
enter code here

Related

Entityframework getting error for saving relationship entities

Problem
I have three model classes Student,Job and Alumni. I created EF DB first approah and I was able to save the Alumni details,But facing the error while saving the Student and Job details.Attached the relationship edmx file for reference.
Issue :
I am facing the error like "An exception of type 'System.Data.Entity.Validation.DbEntityValidationException' occurred in EntityFramework.dll but was not handled in user code" when crearing a new record for Job and Student.
Outcome:
I need to save new records for jobs and students from the EF,I was able to save alumni details
Clarification:
Is there any way to check the query being executed to SQL server from Visual Studio in entity framework other than profiler
JobController:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include="JCompanyName,JobType,JDesignation,JElgibility,JLocation,JYearOfPassed,JPercentReq,JDescription,JAddress,JSalary,JLastDateToApply,JNumberOfVaccancy,JHiringRounds,IsActive,IsCompany")] Job job)
{
if (ModelState.IsValid)
{
db.Jobs.Add(job);
db.SaveChanges(); //Facing the issue here for jobs and Student
//controller
return RedirectToAction("Index");
}
ViewBag.Alumni_ID = new SelectList(db.Alumni, "Id", "AName", job.Alumni_ID);
return View(job);
}
Job Model:
public partial class Job
{
public Job()
{
this.Students = new HashSet<Student>();
}
public int Id { get; set; }
public int Alumni_ID { get; set; }
public string JCompanyName { get; set; }
public string JobType { get; set; }
public string JDesignation { get; set; }
public string JElgibility { get; set; }
public string JLocation { get; set; }
public int JYearOfPassed { get; set; }
public int JPercentReq { get; set; }
public string JDescription { get; set; }
public string JAddress { get; set; }
public string JSalary { get; set; }
public System.DateTime JLastDateToApply { get; set; }
public int JNumberOfVaccancy { get; set; }
public string JHiringRounds { get; set; }
public Nullable<bool> IsActive { get; set; }
public Nullable<bool> IsCompany { get; set; }
public virtual Alumnus Alumnus { get; set; }
public virtual ICollection<Student> Students { get; set; }
}
Student Model:
public partial class Student
{
public int Id { get; set; }
public int Job_Id { get; set; }
public string Sname { get; set; }
public string Sphone { get; set; }
public string SEmail { get; set; }
public string SAddress { get; set; }
public string SchoolName { get; set; }
public string StudyType { get; set; }
public string CollegeOrBoard { get; set; }
public decimal SchoolPercent { get; set; }
public string SchoolState { get; set; }
public string SchoolCity { get; set; }
public string Skills { get; set; }
public string SkillLevel { get; set; }
public string IntermediateName { get; set; }
public string IntermediateStudyType { get; set; }
public string IntermediateBoard { get; set; }
public string IntermediatePercent { get; set; }
public string IntermediateState { get; set; }
public string IntermediateCity { get; set; }
public string UGName { get; set; }
public string UGStream { get; set; }
public string UGStudyType { get; set; }
public string UGBoard { get; set; }
public string UGPercent { get; set; }
public string UGState { get; set; }
public string UGCity { get; set; }
public virtual Job Job { get; set; }
}
Alumns Model:
public partial class Alumnus
{
public Alumnus()
{
this.Jobs = new HashSet<Job>();
}
public int Id { get; set; }
public string AName { get; set; }
public string ACompany { get; set; }
public string APhone { get; set; }
public string AEmail { get; set; }
public string AAddress { get; set; }
public string ACompanyAddress { get; set; }
public int ABatchYear { get; set; }
public virtual ICollection<Job> Jobs { get; set; }
}
SQL Script:
USE [AlumniConnect]
GO
/****** Object: Table [dbo].[Alumni] Script Date: 05/04/2019 21:57:36 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Alumni](
[Id] [int] IDENTITY(1,1) NOT NULL,
[AName] [varchar](500) NOT NULL,
[ACompany] [varchar](500) NOT NULL,
[APhone] [varchar](500) NOT NULL,
[AEmail] [varchar](500) NOT NULL,
[AAddress] [varchar](500) NOT NULL,
[ACompanyAddress] [varchar](500) NOT NULL,
[ABatchYear] [int] NOT NULL,
PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
/****** Object: Table [dbo].[Jobs] Script Date: 05/04/2019 21:57:36 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Jobs](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Alumni_ID] [int] NOT NULL,
[JCompanyName] [varchar](1) NOT NULL,
[JobType] [varchar](1) NOT NULL,
[JDesignation] [varchar](1) NOT NULL,
[JElgibility] [varchar](1) NOT NULL,
[JLocation] [varchar](1) NOT NULL,
[JYearOfPassed] [int] NOT NULL,
[JPercentReq] [int] NOT NULL,
[JDescription] [varchar](max) NOT NULL,
[JAddress] [varchar](max) NOT NULL,
[JSalary] [varchar](max) NOT NULL,
[JLastDateToApply] [date] NOT NULL,
[JNumberOfVaccancy] [int] NOT NULL,
[JHiringRounds] [varchar](max) NOT NULL,
[IsActive] [bit] NULL,
[IsCompany] [bit] NULL,
PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
/****** Object: Table [dbo].[Student] Script Date: 05/04/2019 21:57:36 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Student](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Job_Id] [int] NOT NULL,
[Sname] [varchar](1) NOT NULL,
[Sphone] [varchar](15) NOT NULL,
[SEmail] [varchar](50) NOT NULL,
[SAddress] [varchar](max) NOT NULL,
[SchoolName] [varchar](max) NOT NULL,
[StudyType] [varchar](50) NOT NULL,
[CollegeOrBoard] [varchar](max) NOT NULL,
[SchoolPercent] [decimal](18, 0) NOT NULL,
[SchoolState] [varchar](200) NOT NULL,
[SchoolCity] [varchar](200) NOT NULL,
[Skills] [varchar](500) NOT NULL,
[SkillLevel] [varchar](1) NOT NULL,
[IntermediateName] [varchar](200) NOT NULL,
[IntermediateStudyType] [varchar](500) NOT NULL,
[IntermediateBoard] [varchar](500) NOT NULL,
[IntermediatePercent] [varchar](500) NOT NULL,
[IntermediateState] [varchar](500) NOT NULL,
[IntermediateCity] [varchar](500) NOT NULL,
[UGName] [varchar](500) NOT NULL,
[UGStream] [varchar](500) NOT NULL,
[UGStudyType] [varchar](500) NOT NULL,
[UGBoard] [varchar](500) NOT NULL,
[UGPercent] [varchar](500) NOT NULL,
[UGState] [varchar](500) NOT NULL,
[UGCity] [varchar](500) NOT NULL,
PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
UNIQUE NONCLUSTERED
(
[SEmail] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
UNIQUE NONCLUSTERED
(
[Sphone] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
/****** Object: ForeignKey [Jobs_fk0] Script Date: 05/04/2019 21:57:36 ******/
ALTER TABLE [dbo].[Jobs] WITH CHECK ADD CONSTRAINT [Jobs_fk0] FOREIGN KEY([Alumni_ID])
REFERENCES [dbo].[Alumni] ([Id])
GO
ALTER TABLE [dbo].[Jobs] CHECK CONSTRAINT [Jobs_fk0]
GO
/****** Object: ForeignKey [Student_fk0] Script Date: 05/04/2019 21:57:36 ******/
ALTER TABLE [dbo].[Student] WITH CHECK ADD CONSTRAINT [Student_fk0] FOREIGN KEY([Job_Id])
REFERENCES [dbo].[Jobs] ([Id])
GO
ALTER TABLE [dbo].[Student] CHECK CONSTRAINT [Student_fk0]
GO
The pattern of saving here matters because of db dependencies
Try This
[HttpPost]
[ValidateAntiForgeryToken]
//I removed the binding so the answer can be clearer, you can still include it but you need to pass the models. I don't know if you have passed them before
public ActionResult Create(Job job, Student student, Alumni alumni)
{
if (ModelState.IsValid)
{
//you will have to save in this pattern Alumni first, Job second, Student last
db.Alumni.Add(alumni);
db.SaveChanges();
//save the job
job.Alunmi_ID = alumni.Id
db.Job.Add(job)
db.SaveChanges()
//save the student
student.Job_ID = job.Id
db.Student.Add(student)
db.SaveChanges()
return RedirectToAction("Index");
}
ViewBag.Alumni_ID = new SelectList(db.Alumni, "Id", "AName", job.Alumni_ID);
return View(job);
}

i have created scaffolding in MVC. After filling data in the form when I click on create button, below error occurs

This is the error i get when I'm trying to save data to my table.
Error:
An exception of type
'System.Data.Entity.Infrastructure.DbUpdateException' occurred in
EntityFramework.dll but was not handled in user code
Additional information: Unable to update the EntitySet
'CustormerD' because it has a DefiningQuery and no
<InsertFunction> element exists in the
<ModificationFunctionMapping> element to support the current
operation.
Controller Code:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include="custid,name,cell_No,address,date,time,serviceNo")] CustormerD custormerd)
{
if (ModelState.IsValid)
{
db.CustormerDs.Add(custormerd);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(custormerd);
}
table code below:
public partial class CustormerD
{
public int custid { get; set; }
public string name { get; set; }
public Nullable<int> cell_No { get; set; }
public string address { get; set; }
public Nullable<System.DateTime> date { get; set; }
public Nullable<System.TimeSpan> time { get; set; }
public Nullable<int> serviceNo { get; set; }
}
sql code
CREATE TABLE [dbo].[CustormerD](
[custid] [int] IDENTITY(1,1) NOT NULL,
[name] [nchar](20) NULL,
[cell_No] [int] NULL,
[address] [nchar](20) NULL,
[date] [date] NULL,
[time] [time](7) NULL,
[serviceNo] [int] NULL
) ON [PRIMARY]
As per discussed in comment OP use .edmxfile.
So you can set primary key to your table like following:
USE [yourdatbase]
GO
/****** Object: Table [dbo].[CustormerD] Script Date: 26/09/2016 4:08:23 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[CustormerD](
[custid] [int] IDENTITY(1,1) NOT NULL,
[name] [nchar](20) NULL,
[cell_No] [int] NULL,
[address] [nchar](20) NULL,
[date] [date] NULL,
[time] [time](7) NULL,
[serviceNo] [int] NULL,
CONSTRAINT [PK_CustormerD] PRIMARY KEY CLUSTERED
(
[custid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
After set the primary key, you should update your .edmx model from the database.
The Entity Framework will only assume a primary key from your model if the name of the field is the name of the model + ID. Otherwise you will have to explicitly state which field to use as a primary key. For your model that would mean either changing the name of your primary key to:
public int CustomerDID { get; set; }
Entity framework would then automatically assume it as the primary key. Alternatively you label your primary key using [Key] as follows:
public partial class CustormerD
{
[Key]
public int custid { get; set; }
public string name { get; set; }
public Nullable<int> cell_No { get; set; }
public string address { get; set; }
public Nullable<System.DateTime> date { get; set; }
public Nullable<System.TimeSpan> time { get; set; }
public Nullable<int> serviceNo { get; set; }
}

MVC 4 App - Get data from database

First of all I'd like to say, that I am super new to the MVC pattern, sorry if I am asking a stupid question.
My problem:
I am having trouble with the building of a profile page for my users. If a user goes to that page it's going to list information about them, like e-mail address, phone number, full name, etc..
Note:
I am using the "Basic" project template with SimpleMemberShipProvider hadling user actions.
The problem comes with the database querying, to get the necessary data about the user.
Here's my UserProfile table data:
CREATE TABLE [dbo].[UserProfile] (
[UserId] INT IDENTITY (1, 1) NOT NULL,
[UserName] NVARCHAR (MAX) NULL,
[FirstName] NVARCHAR (MAX) NULL,
[LastName] NVARCHAR (MAX) NULL,
[Age] INT NULL,
[Sex] NVARCHAR (MAX) NULL,
[SecretQuestion] NVARCHAR (MAX) NULL,
[SecretQuestionAnswer] NVARCHAR (MAX) NULL,
[MoneyIn] INT NULL,
[MoneyOut] INT NULL,
[TimesWon] INT NULL,
[Email] NVARCHAR (MAX) DEFAULT ('') NOT NULL,
[PhoneNumber] NVARCHAR (MAX) NULL,
[Address] NVARCHAR (MAX) NULL,
CONSTRAINT [PK_dbo.UserProfile] PRIMARY KEY CLUSTERED ([UserId] ASC)
);
My 'User' model:
[Table("UserProfile")]
public class User
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
[Column("UserName")]
public string UserName { get; set; }
[Column("Email")]
[Required]
public string Email { get; set; }
[Column("FirstName")]
public string FirstName { get; set; }
[Column("LastName")]
public string LastName { get; set; }
[Column("PhoneNumber")]
public string PhoneNumber { get; set; }
[Column("Address")]
public string Address { get; set; }
[Column("Age")]
[Required]
public int Age { get; set; }
[Column("Sex")]
public string Sex { get; set; }
[Column("SecretQuestion")]
[Required]
public string SecretQuestion { get; set; }
[Column("SecretQuestionAnswer")]
[Required]
public string SecretQuestionAnswer { get; set; }
[Column("MoneyIn")]
public int MoneyIn { get; set; }
[Column("MoneyOut")]
public int MoneyOut { get; set; }
[Column("TimesWon")]
public int TimesWon { get; set; }
}
Here's my DbContext class:
public DbSet<User> Users { get; set; }
My controller with the 'Profile' action:
[Authorize]
public ActionResult Profil()
{
var model = db.Users.ToList();
return View(model);
}
And finally some relevant parts of my view to display the data:
#model IEnumerable<OneMillion.Models.User>
#foreach (var item in Model)
{
#item.FirstName
}
The error I get when trying to access the page as a logged in user:
Server Error in '/' Application.
The 'MoneyIn' property on 'User' could not be set to a 'null' value. You must set this property to a non-null value of type 'Int32'.
Thanks!
try to set the properties to be a nullable type ->
[Column("MoneyIn")]
public int? MoneyIn { get; set; }
[Column("MoneyOut")]
public int? MoneyOut { get; set; }
Your model and database definitions don't match, you have nullable fields in the database definition (Age, MoneyIn, MoneyOut and TimesWon) but non-nullable fields in the model.

MVC Code First Entity Frame Work reference same oject twice from master object

Have a code first MVC4 model that requires foreign key look up to the same table. i.e My Project table has two columns (BaseFiscalId and IMITApprovalCycleId) that reference the same table i.e. FiscalYears. How do I define this in the code.
Currently I have the following:
public class Project
{
[Required]
public int Id { get; set; }
[Required]
public int InitiativeId { get; set; }
[Required]
public String ProjectName { get; set; }
[Required]
public int SubPortFolioId { get; set; }
[Required]
public String Description { get; set; }
[Required]
public int ProjectTypeId { get; set; }
[Required]
public int FundingSourceId { get; set; }
[Required]
public int FundingPhaseAId { get; set; }
[Required]
public int ApprovalStatusId { get; set; }
[Required]
public int IMITApprovalProcessId { get; set; }
[Required]
public int IMITApprovalCycleId { get; set; }
[Required]
public int AccountableExecutiveId { get; set; }
[Required]
public int LeadMinistryId { get; set; }
[Required]
public int BaseFiscalId { get; set; }
[Required]
public int TotalSpentToBase { get; set; }
//Navigation Properties --Child Projects
public ICollection<Spend> Spends { get; set; }
public SubPortfolio SubPortfolio { get; set; }
public ProjectType ProjectType { get; set; }
public FundingPhase FundingPhase { get; set; }
public FundingSource FundingSource { get; set; }
public ApprovalStatus ApprovalStatus { get; set; }
public IMITApprovalProcess IMITApprovalProcess { get; set; }
public FiscalYear IMITApprovalCycle { get; set; }
public FiscalYear BaseFiscal { get; set; }
public Portfolio Portfolio { get; set; }
public Executive AccountableExecutive { get; set; }
public Ministry LeadMinistry { get; set; }
public Initiative Initiative { get; set; }
}
FiscalYears Class
public class FiscalYear
{
[ScaffoldColumn(false)]
public int Id { get; set; }
[Required]
public String FiscalYearName { get; set; }
}
This results in the following SQL:
CREATE TABLE [dbo].[Projects] (
[Id] INT NOT NULL,
[InitiativeId] INT NOT NULL,
[ProjectName] NVARCHAR (MAX) NOT NULL,
[SubPortFolioId] INT NOT NULL,
[Description] NVARCHAR (MAX) NOT NULL,
[ProjectTypeId] INT NOT NULL,
[FundingSourceId] INT NOT NULL,
[FundingPhaseAId] INT NOT NULL,
[ApprovalStatusId] INT NOT NULL,
[IMITApprovalProcessId] INT NOT NULL,
[IMITApprovalCycleId] INT NOT NULL,
[AccountableExecutiveId] INT NOT NULL,
[LeadMinistryId] INT NOT NULL,
[BaseFiscalId] INT NOT NULL,
[TotalSpentToBase] INT NOT NULL,
[FundingPhase_Id] INT NULL,
[Portfolio_Id] INT NULL,
[Initiative_Id] INT NULL,
CONSTRAINT [PK_dbo.Projects] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_dbo.Projects_dbo.SubPortfolios_SubPortFolioId] FOREIGN KEY ([SubPortFolioId]) REFERENCES [dbo].[SubPortfolios] ([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_dbo.Projects_dbo.ProjectTypes_ProjectTypeId] FOREIGN KEY ([ProjectTypeId]) REFERENCES [dbo].[ProjectTypes] ([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_dbo.Projects_dbo.FundingPhases_FundingPhase_Id] FOREIGN KEY ([FundingPhase_Id]) REFERENCES [dbo].[FundingPhases] ([Id]),
CONSTRAINT [FK_dbo.Projects_dbo.FundingSources_FundingSourceId] FOREIGN KEY ([FundingSourceId]) REFERENCES [dbo].[FundingSources] ([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_dbo.Projects_dbo.ApprovalStatus_ApprovalStatusId] FOREIGN KEY ([ApprovalStatusId]) REFERENCES [dbo].[ApprovalStatus] ([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_dbo.Projects_dbo.IMITApprovalProcesses_IMITApprovalProcessId] FOREIGN KEY ([IMITApprovalProcessId]) REFERENCES [dbo].[IMITApprovalProcesses] ([Id]) ON DELETE CASCADE,
**CONSTRAINT [FK_dbo.Projects_dbo.FiscalYears_Id] FOREIGN KEY ([Id]) REFERENCES [dbo].[FiscalYears] ([Id])**,
CONSTRAINT [FK_dbo.Projects_dbo.Portfolios_Portfolio_Id] FOREIGN KEY ([Portfolio_Id]) REFERENCES [dbo].[Portfolios] ([Id]),
CONSTRAINT [FK_dbo.Projects_dbo.Executives_AccountableExecutiveId] FOREIGN KEY ([AccountableExecutiveId]) REFERENCES [dbo].[Executives] ([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_dbo.Projects_dbo.Ministries_LeadMinistryId] FOREIGN KEY ([LeadMinistryId]) REFERENCES [dbo].[Ministries] ([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_dbo.Projects_dbo.Initiatives_Initiative_Id] FOREIGN KEY ([Initiative_Id]) REFERENCES [dbo].[Initiatives] ([Id])
Note instead of creating two FK relationships to FiscalYears One each for BaseFiscal and IMITApprovalCycle it create only on on Fiscal_Id which does not exist in the Projects Table.
Thanks
Craig

EF Code First 4.3 Self Referencing Zero to Many

I'm trying to define a self referencing relationship for a workflow step where that step is not available to be kicked off until all of its dependent steps have been completed. A step can have zero or many dependencies. I have the following but, EF doesn't map this correctly. Instead it creates the following table which does not meet my needs. How can I achieve this?
Class:
public class WorkflowStepDefinition : EntityBase, IAudited {
[Key]
public int WorkflowStepDefinitionId { get; set; }
[MaxLength(100)]
public string Name { get; set; }
public string Description { get; set; }
public int WorkflowDefinitionId { get; set; }
public virtual WorkflowDefinition WorkflowDefinition { get; set; }
public virtual IList<WorkflowStep> WorkflowSteps { get; set; }
public virtual IList<WorkflowStepDefinition> DependsOn { get; set; }
public AuditDetails Audit { get; set; }
}
Table Def:
CREATE TABLE [dbo].[WorkflowStepDefinitions](
[WorkflowStepDefinitionId] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](100) NOT NULL,
[Description] [nvarchar](max) NULL,
[WorkflowDefinitionId] [int] NOT NULL,
[Audit_CreatedBy] [nvarchar](max) NOT NULL,
[Audit_DateCreated] [datetimeoffset](7) NOT NULL,
[Audit_UpdatedBy] [nvarchar](max) NULL,
[Audit_DateUpdated] [datetimeoffset](7) NULL,
[WorkflowStepDefinition_WorkflowStepDefinitionId] [int] NULL,
CONSTRAINT [PK_WorkflowStepDefinitions] PRIMARY KEY CLUSTERED
(
[WorkflowStepDefinitionId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[WorkflowStepDefinitions] WITH CHECK ADD CONSTRAINT [FK_WorkflowStepDefinitions_WorkflowDefinitions_WorkflowDefinitionId] FOREIGN KEY([WorkflowDefinitionId])
REFERENCES [dbo].[WorkflowDefinitions] ([WorkflowDefinitionId])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[WorkflowStepDefinitions] CHECK CONSTRAINT [FK_WorkflowStepDefinitions_WorkflowDefinitions_WorkflowDefinitionId]
GO
ALTER TABLE [dbo].[WorkflowStepDefinitions] WITH CHECK ADD CONSTRAINT [FK_WorkflowStepDefinitions_WorkflowStepDefinitions_WorkflowStepDefinition_WorkflowStepDefinitionId] FOREIGN KEY([WorkflowStepDefinition_WorkflowStepDefinitionId])
REFERENCES [dbo].[WorkflowStepDefinitions] ([WorkflowStepDefinitionId])
GO
ALTER TABLE [dbo].[WorkflowStepDefinitions] CHECK CONSTRAINT [FK_WorkflowStepDefinitions_WorkflowStepDefinitions_WorkflowStepDefinition_WorkflowStepDefinitionId]
GO
Edit:
Ideally I think I'd like something that produces a join table such as:
CREATE TABLE [dbo].[WorkflowStepDefinitionDependencies](
WorkflowStepDefinitionId int NOT NULL,
DependencyId int NOT NULL
)
As mentioned in comment you can achieve this with fluent API which also gives you possibility to name your junction table and FKs in the junction table:
modelBuilder.Entity<WorkflowStepDefinition>()
.HasMany(w => w.DependsOn)
.WithMany()
.Map(mc =>
{
mc.ToTable("WorkflowStepDefinitionDependencies", "dbo");
mc.MapLeftKey("WorkflowStepDefinitionId");
mc.MapRightKey("DependencyId");
});

Resources