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");
});
Related
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 primary table Student and foreign Table Academic
public partial class StudentInfo
{
public StudentInfo()
{
this.StudentCurrentAcademics = new HashSet<Academic>();
}
public int StudentInfoID { get; set; }
public Nullable<int> BranchID { get; set; }
public string ScholarID { get; set; }
public string Religion { get; set; }
public virtual ICollection<Academic> StudentCurrentAcademics { get; set; }
}
and my foregin table is
public partial class Academic
{
public decimal CurrentAcademicID { get; set; }
public Nullable<int> StudentInfoID { get; set; }
public Nullable<int> CourseID { get; set; }
public Nullable<int> StandardID { get; set; }
public virtual StudentInfo StudentInfo { get; set; }
}
I want to update both the table same time using
I initialized StudentInfo table object with Academic object.
I have set StudentInfoID in both tables.
Now updating it using
_context.Entry(StudentInfoObj).State = System.Data.Entity.EntityState.Modified;
_context.SaveChanges();
It's updating StudentInfo record in database but not updating Academic record.
Please try exactly as I do and it works. Your entity name and database will be different. The SaveChanges() will act as a transaction, so your updates will happened 'at the same time'.
SQL:
USE [Breaz]
GO
/****** Object: Table [dbo].[Academic] Script Date: 2/21/2017 3:18:37 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Academic](
[CurrentAcedemicID] [int] IDENTITY(1,1) NOT NULL,
[StudentInfoID] [int] NULL,
[CourseID] [int] NULL,
[StandardID] [int] NULL,
CONSTRAINT [PK_Academic] PRIMARY KEY CLUSTERED
(
[CurrentAcedemicID] 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
/****** Object: Table [dbo].[StudentInfo] Script Date: 2/21/2017 3:18:37 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[StudentInfo](
[StudentInfoID] [int] IDENTITY(1,1) NOT NULL,
[BranchID] [int] NULL,
[ScholarID] [varchar](10) NOT NULL,
[Religion] [varchar](10) NOT NULL,
CONSTRAINT [PK_StudentInfo] PRIMARY KEY CLUSTERED
(
[StudentInfoID] 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
SET IDENTITY_INSERT [dbo].[Academic] ON
GO
INSERT [dbo].[Academic] ([CurrentAcedemicID], [StudentInfoID], [CourseID], [StandardID]) VALUES (1, 1, 2, 3)
GO
INSERT [dbo].[Academic] ([CurrentAcedemicID], [StudentInfoID], [CourseID], [StandardID]) VALUES (2, 1, 3, 5)
GO
SET IDENTITY_INSERT [dbo].[Academic] OFF
GO
SET IDENTITY_INSERT [dbo].[StudentInfo] ON
GO
INSERT [dbo].[StudentInfo] ([StudentInfoID], [BranchID], [ScholarID], [Religion]) VALUES (1, 1, N'1', N'na')
GO
SET IDENTITY_INSERT [dbo].[StudentInfo] OFF
GO
ALTER TABLE [dbo].[Academic] WITH CHECK ADD CONSTRAINT [FK_Academic_StudentInfo] FOREIGN KEY([StudentInfoID])
REFERENCES [dbo].[StudentInfo] ([StudentInfoID])
GO
ALTER TABLE [dbo].[Academic] CHECK CONSTRAINT [FK_Academic_StudentInfo]
GO
Add the EDMX
Here is the Controller
public class HomeController : Controller
{
public ActionResult Index23()
{
using (BreazEntities5 entity = new BreazEntities5())
{
var student = entity.StudentInfoes.Where(r => r.StudentInfoID == 1).
Include(s => s.Academics).FirstOrDefault();
student.Religion = "need more";
student.Academics.ToList().ForEach(r => r.CourseID = 999);
entity.Entry(student).State = System.Data.Entity.EntityState.Modified;
entity.SaveChanges();
}
return View();
}
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; }
}
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
The application I'm working on generates an error while creating an instance of a model. I have Product and Color (many to many) and ProductImage (many ProductImage to a ProductColor).
public partial class ProductColor
{
public ProductColor()
{
this.ProductImages = new HashSet<ProductImage>();
}
public int Id { get; set; }
[DefaultValue(0),DisplayName("Price Offset")]
public Decimal PriceOffset { get; set; }
public int ProductId { get; set; }
public int ColorId { get; set; }
public virtual Color Color { get; set; }
public virtual Product Product { get; set; }
public virtual ICollection<ProductImage> ProductImages { get; set; }
}
public partial class ProductImage
{
public int Id { get; set; }
[DisplayName("File name"),
Required(),
StringLength(255)]
public string FileName { get; set; }
public bool Default { get; set; }
public int ProductColor_Id { get; set; }
public virtual ProductColor ProductColor { get; set; }
}
public class testContext : DbContext
{
public testContext() : base("name=testContext")
{
}
public DbSet<Product> Products { get; set; }
public DbSet<Manufacturer> Manufacturers { get; set; }
public DbSet<ProductColor> ProductColors { get; set; }
public DbSet<Color> Colors { get; set; }
public DbSet<ProductImage> ProductImages { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Product>()
.HasMany(c => c.ProductColors);
}
}
After scaffolding the controller and views for ProductImage and going to the index of ProductImage I get an error trying to get ProductImages from the db context.
No wonder because Entity decided the following sql should be used to get the instances:
SELECT
[Extent1].[Id] AS [Id],
[Extent1].[FileName] AS [FileName],
[Extent1].[Default] AS [Default],
[Extent1].[ProductColor_Id] AS [ProductColor_Id],
[Extent1].[ProductColor_Id1] AS [ProductColor_Id1]
FROM [dbo].[ProductImages] AS [Extent1]
ProductColor_Id1 does not exist in the database. Here is the sql that created the tables:
CREATE TABLE [dbo].[ProductColors] (
[Id] int IDENTITY(1,1) NOT NULL,
[PriceOffset] decimal(7,2) NOT NULL,
[ProductId] int NOT NULL,
[ColorId] int NOT NULL
);
CREATE TABLE [dbo].[ProductImages] (
[Id] int IDENTITY(1,1) NOT NULL,
[FileName] nvarchar(255) NOT NULL,
[Default] bit NOT NULL,
[ProductColor_Id] int NOT NULL
);
ALTER TABLE [dbo].[ProductColors]
ADD CONSTRAINT [PK_ProductColors]
PRIMARY KEY CLUSTERED ([Id] ASC);
ALTER TABLE [dbo].[ProductColors]
ADD CONSTRAINT [FK_ProductColorColor]
FOREIGN KEY ([ColorId])
REFERENCES [dbo].[Colors]
([Id])
ON DELETE NO ACTION ON UPDATE NO ACTION;
CREATE INDEX [IX_FK_ProductColorColor]
ON [dbo].[ProductColors]
([ColorId]);
ALTER TABLE [dbo].[ProductColors]
ADD CONSTRAINT [FK_ProductColorProduct]
FOREIGN KEY ([ProductId])
REFERENCES [dbo].[Products]
([Id])
ON DELETE NO ACTION ON UPDATE NO ACTION;
CREATE INDEX [IX_FK_ProductColorProduct]
ON [dbo].[ProductColors]
([ProductId]);
ALTER TABLE [dbo].[ProductImages]
ADD CONSTRAINT [FK_ProductColorProductImage]
FOREIGN KEY ([ProductColor_Id])
REFERENCES [dbo].[ProductColors]
([Id])
ON DELETE NO ACTION ON UPDATE NO ACTION;
CREATE INDEX [IX_FK_ProductColorProductImage]
ON [dbo].[ProductImages]
([ProductColor_Id]);
The database is generated from an Entity diagram and looks fine to me. I have no idea why on a ProductImage create it added ProductColor_Id1 in the select statement.
Hope there is enough information provided and that this is a general mistake that's easily solved. Thank you for reading this and hope you can help.
I would like the scaffolded controller and views to work in listing, creating, editing and deleting the ProdcutImage objects but as it is it's not even possible to create one with the information provided to Entity.
After deleting and re creating the association in the Entity diagram I ended up with a ProductImage having ProductColorId instead of ProductColor_Id.
Not too sure what I did differently (maybe checked the "Add foreign key properties to ProductImage entity" in the diagram.
Re created database from diagram and re created model classes from database (to be used in another project). The ProductImage now looks like this:
public partial class ProductImage
{
public int Id { get; set; }
[DisplayName("File name"),
Required(),
StringLength(255)]
public string FileName { get; set; }
public bool Default { get; set; }
public int ProductColorId { get; set; }
public virtual ProductColor ProductColor { get; set; }
}
As far as I can see the only difference is ProductColerId, must be a convention in Entity to specify relations this way.
A tip when working in the diagram:
In a one to many first click the one side (in my case one ProductColor has many ProductImage so I right click on ProductColor). Then when choosing add new => association it automatically sets ProductColor (the clicked item) to one. Now setting the many relation on the right side will automatically check the "add foreign key" checkbox.
If I were to click on the many side first (right click on ProductImage). Then change the left side dropdown to many and right side select ProductColor with one for multiplicity then the "add foreign key" check box needs to be checked manually.