I'm trying to create a many-to-many relationship between my two tables, but when I run Update-Database command I get this error:
Introducing FOREIGN KEY constraint 'FK_dbo.ExamQuestions_dbo.Questions_Question_Id' on table 'ExamQuestions' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Could not create constraint or index. See previous errors.
My first entity is :
public class Question
{
public Question()
{
this.Exams = new HashSet<Exam>();
}
[Key]
public int Id { get; set; }
[Required(ErrorMessage="Question is Required")]
[Display(Name="Question")]
[AllowHtml]
public string QuestionText { get; set; }
// public bool IsMultiSelect { get; set; }
public string Hint { get; set; }
public string HelpLink { get; set; }
public int Marks { get; set; }
public byte[] ImageData { get; set; }
[StringLength(50)]
public string MimeType { get; set; }
public byte[] Audio { get; set; }
public int QuestionTypeId { get; set; }
public int TopicId { get; set; }
public int DifficulityLevelId { get; set; }
public int SubjectId { get; set; }
public DifficultyLevel QuestionDifficulity { get; set; }
public Topic Topic { get; set; }
public virtual ICollection<Option> Options { get; set; }
public ICollection<Exam> Exams { get; set; }
}
And the second entity is:
public class Exam
{
public Exam()
{
this.Questions = new HashSet<Question>();
}
[Key]
public int Id { get; set; }
[Required]
public string Name { get; set; }
[Required]
public int Duration { get; set; }
[Required]
public int TotalQuestion { get; set; }
[Required]
public int TotalMarks { get; set; }
public bool SectionWiseTime { get; set; }
public bool QuestionWiseTime { get; set; }
public bool AllQustionRequired { get; set; }
public bool AllowBackForward { get; set; }
public bool SuffleSubjectWise { get; set; }
public bool SuffleOptionWise { get; set; }
public bool GroupSubjectWise { get; set; }
[Required]
public int ExamTypeId { get; set; }
[Required]
public int ExamInstructionId { get; set; }
[Required]
public int DifficultyLevelId { get; set; }
public virtual ExamType ExamType { get; set; }
public virtual ExamInstruction ExamInstruction { get; set; }
public virtual DifficultyLevel DifficultyLevel { get; set; }
public virtual ICollection<Question> Questions { get; set; }
//public virtual ICollection<ExamSchedule> ExamSchedules { get; set; }
}
Can someone tell me where I'm going wrong?
By default, EF has cascading deletes set. This error is warning you that this can cause cascading deletes with many to many relationships. And is probably not what you intend to have happen on a delete/update.
You can remove the OneToManyCascadeDeleteConvention in the OnModelCreating method, or on the fluent mapping for each entity.
Details are provided in this SO Answer
Related
My target with the below mentioned classes is to make one DTOs class out of these classes and register AppUser in sqlite database. I use Identity core. I thank you for every body who has given me help on solving this problem.
By the way: is that possible to have virutal properties inside DTO classes? Other thing which i am struggling with is on how to handle the incoming user input (in this case DTO). I get the following error time and again Cannot implicitly convert type int to Backend.Data.Gender. I Cannot implicitly convert type Backend.Data.Work_Experience to System.Collections.Generic.List<Backend.Data.Work_Experience>
public class AppUser : IdentityUser<int>
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Description { get; set; }
virtual public Gender Gender { get; set; }
virtual public ICollection<Interest> Interests {get; set;}
virtual public List<Education> Education { get; set; }
virtual public List<Work_Experience> Work_Experiences { get; set; }
virtual public List<Answer> Answers { get; set; }
}
public class Interest
{
[Key]
public int Id { get; set; }
public string InterestName{ get; set; }
public virtual ICollection<AppUser> Users { get; set; }
}
public class Education
{
[Key]
public int EducationsId { get; set; }
public string SchoolName { get; set; }
public string Field_Of_Study { get; set; }
public string StudyPath { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public int DegreeId { get; set; }
public virtual Degree Degree { get; set; }
public int UserId { get; set; }
public virtual AppUser User { get; set; }
}
public class Degree
{
[Key]
public int DegreesId { get; set; }
public string DegreeName { get; set; }
}
public class Gender
{
[Key]
public int GenderId { get; set; }
public string GenderName { get; set; }
}
public class Work_Experience
{
[Key]
public int WorkExperiencesId { get; set; }
public string JobTitle { get; set; }
public string CompanyName { get; set; }
public string Industry { get; set; }
public string Field_Of_Work { get; set; }
public int UserId { get; set; }
public virtual AppUser User { get; set; }
}
public class Question
{
[Key]
public int QuestionsId { get; set; }
public string Question_text { get; set; }
}
public class Answer
{
[Key]
public int AnswersId { get; set; }
public string Answer_text { get; set; }
public int QuestionId { get; set; }
public virtual Question Question { get; set; }
public int UserId { get; set; }
public virtual AppUser User { get; set; }
}
Here is my Schema and with two Foreign Key in an intermediate table. I am beginner in Core dotnet so unable to crate API to show the department in the school.
public class DepartmentSchool
{
public int Id { get; set; }
public int DepartmentID { get; set; }
[ForeignKey("DepartmentID")]
public virtual Department Department{ get; set; }
public int SchoolsId { get; set; }
[ForeignKey("SchoolsId")]
public virtual Schools Schools { get; set; }
Here I want to get all department related to school id, how can i get all the department though the School id in dotnetcore API.
Here is the school class entity schema.
public partial class Schools
{
public int ID { get; set; }
public string UicCode { get; set; }
public int SchoolSystemsId { get; set; }
public string BannerUrl { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string ImageUrl { get; set; }
public int UserID { get; set; }
public int? Status { get; set; }
public DateTime? CreatedAt { get; set; }
public int? CreatedBy { get; set; }
public DateTime UpdatedAt { get; set; }
public int? ModifiedBy { get; set; }
[ForeignKey("SchoolSystemsId")]
public PrivateSchoolSystem PrivateSchoolSystems { get; set; }
And more here is the department schema.
public partial class Department
{
public int Id { get; set; }
public string Title { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
public int CreatedBy { get; set; }
public int UpdatedBy { get; set; }
public int SchoolSystemsID { get; set; }
[ForeignKey("SchoolSystemsID")]
public virtual PrivateSchoolSystem PrivateSchoolSystems { get; set; }
And I am trying to get a department list in the query in the following controller.
[Route("api/[controller]")]
[ApiController]
public class DepartmentSchoolController : ControllerBase
{
private readonly learning_gpsContext _learning_GpsContext;
public DepartmentSchoolController(learning_gpsContext learning_GpsContext)
{
_learning_GpsContext = learning_GpsContext;
}
[HttpGet("school/{schoolId}/departments")]
public IActionResult GetDepartmentsFromSchool(int schoolId)
{
var school = _learning_GpsContext.Schools.Where(e=>e.Id == schoolId).FirstOrDefault();
if (school == null)
return NotFound();
var departments = _learning_GpsContext.DepartmentSchool
.Where(e=>e.SchoolsId == schoolId).Select(e=>e.Department);
return Ok(departments);
}
For further learning check this tutorial. You should also understand what REST is and for basic questions always take a look at the official documenation.
I have implemented asp .net application without Code first approach. now i want to build different system with existing database and code first.
public class EmployeeEntity
{
public int Id { get; set; }
public string ResourceCode { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
public int Gender { get; set; }
public int Status { get; set; }
public string NIC { get; set; }
}
now i want to add code first entities.
[Table("ExternalApplicantEntity")]
public class ExternalApplicantEntity
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ApplicantID { get; set; }
//[ForeignKey("EmployeeEntity")]
//public int Created_By { get; set; }
//public virtual EmployeeEntity EmployeeEntity { get; set; }
public string NIC { get; set; }
public string Mobile { get; set; }
public string Institute { get; set; }
how i combine these codes?
I'll open with the statement that I am very new to .net and MVC so please bear with me. I'm using Visual Studio 2013 and learning as I go.
Essentially - I have a .net MVC database-first project connected to a SQL db. I used scaffolding to create 4 models -
(Survey_Header_Response) - base survey information, identifies which survey a respondent gets
(Survey_Question) holds a unique list of the questions for all surveys and provides the actual question text,
(Survey_Response) lists of all the questions in the survey identified in (Survey_Response_Header) and will hold the value of each answer on post,
(Response_Values) - holds a list of possible responses for each of the different questions in each survey . Information on these is as follows:
Note - models are scaffolded, so even if I change them, they change back on db update.
Survey_Response_Header model:
public partial class Survey_Response
{
public Survey_Response()
{
this.Response_Values = new HashSet<Response_Values>();
}
public int Survey_Response_RecID { get; set; }
public int Survey_RecID { get; set; }
public int Survey_Question_RecID { get; set; }
public string Response { get; set; }
public Nullable<System.DateTime> Date_Responded { get; set; }
public int Contact_RecID { get; set; }
public int Company_RecID { get; set; }
public System.DateTime Date_Sent { get; set; }
public bool Responded { get; set; }
public string Survey_Qtr { get; set; }
public System.Guid Respondent_ID { get; set; }
public virtual Survey_Detail Survey_Detail { get; set; }
public virtual Survey_Question Survey_Question { get; set; }
public virtual ICollection<Response_Values> Response_Values { get; set; }
public virtual Survey_Response_Header Survey_Response_Header { get; set; }
}
Survey_Question:
public partial class Survey_Question
{
public Survey_Question()
{
this.Survey_Cat_SubCat = new HashSet<Survey_Cat_SubCat>();
this.Survey_Detail = new HashSet<Survey_Detail>();
this.Response_Values = new HashSet<Response_Values>();
this.Survey_Response = new HashSet<Survey_Response>();
}
public int Survey_Question_RecID { get; set; }
public string Question { get; set; }
public bool Inactive_Flag { get; set; }
public System.DateTime Date_Created { get; set; }
public string Created_By { get; set; }
public System.DateTime Date_Updated { get; set; }
public string Updated_By { get; set; }
public virtual ICollection<Survey_Cat_SubCat> Survey_Cat_SubCat { get; set; }
public virtual ICollection<Survey_Detail> Survey_Detail { get; set; }
public virtual ICollection<Response_Values> Response_Values { get; set; }
public virtual ICollection<Survey_Response> Survey_Response { get; set; }
}
Survey Response:
public Survey_Response()
{
this.Response_Values = new HashSet<Response_Values>();
}
public int Survey_Response_RecID { get; set; }
public int Survey_RecID { get; set; }
public int Survey_Question_RecID { get; set; }
public string Response { get; set; }
public Nullable<System.DateTime> Date_Responded { get; set; }
public int Contact_RecID { get; set; }
public int Company_RecID { get; set; }
public System.DateTime Date_Sent { get; set; }
public bool Responded { get; set; }
public string Survey_Qtr { get; set; }
public System.Guid Respondent_ID { get; set; }
public virtual Survey_Detail Survey_Detail { get; set; }
public virtual Survey_Question Survey_Question { get; set; }
public virtual ICollection<Response_Values> Response_Values { get; set; }
public virtual Survey_Response_Header Survey_Response_Header { get; set; }
}
Response_Values:
public partial class Response_Values
{
public Response_Values()
{
this.Survey_Response = new HashSet<Survey_Response>();
}
public int Survey_RecID { get; set; }
public int Survey_Question_RecID { get; set; }
public int Value { get; set; }
public int Question_Type_RecID { get; set; }
public string Value_Label { get; set; }
public Nullable<System.DateTime> Date_Created { get; set; }
public string Created_By { get; set; }
public Nullable<System.DateTime> Date_Updated { get; set; }
public string Updated_By { get; set; }
public int Response_Value_RecID { get; set; }
public virtual Question_Type Question_Type { get; set; }
public virtual Survey_Question Survey_Question { get; set; }
public virtual Survey Survey { get; set; }
public virtual Survey_Detail Survey_Detail { get; set; }
public virtual ICollection<Survey_Response> Survey_Response { get; set; }
}
}
There is a many-to-many relationship between the Response_Values & Survey_Response tables through the use of a pure-join table not shown here.
ViewModels: (See edit below)
ResponseData (intended to hold Survey_Response data and reference related tables)
I apologize for the length of this question - I'm new at this so my coding is probably messy and my explanation long. Any help provided is much appreciated and will help me learn!
Edit:
Thanks for your reply. I understand where you're coming from, and I've attempted to build the controller but when I try to populate the ResponseData viewModel that contains the ICollection Survey_Response with data, I get an error "Cannot implicitly convert type 'System.Collections.Generic.List CustomerExperienceSurveyWeb.Models.Survey_Response' to 'System.Collections.Generic.ICollection CustomerExperienceSurveyWeb.ViewModels.SurveyResponseVM'. An explicit conversion exists (are you missing a cast?)"
Here's the relevant part of my controller code:
public ActionResult Edit(Guid id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
//Survey_Response_Header survey = db.Survey_Response_Header.Find(id);
var survey = db.Survey_Response_Header
.Include(i => i.Survey_Response)
.Where(i => i.Responded_ID == id)
.Select(i => new
{
ViewModel = new ResponseData
{
Responded_ID = i.Responded_ID,
Company_RecID = i.Company_RecID,
Contact = i.Contact,
Contact_RecID = i.Contact_RecID,
Date_Responsed = i.Date_Responsed,
Date_Sent = i.Date_Sent,
Responded = i.Responded,
Survey_Qtr = i.Survey_Qtr,
Survey_RecID = i.Survey_RecID,
SurveyResponse = i.Survey_Response.ToList() <<--- This is where the error shows
}
})
.Single();
Updated ResponseData viewModel:
public partial class ResponseData
{
public ResponseData()
{
this.SurveyResponse = new List<SurveyResponseVM>();
}
public System.Guid Responded_ID { get; set; }
public int Survey_RecID { get; set; }
public System.DateTime Date_Sent { get; set; }
public Nullable<System.DateTime> Date_Responsed { get; set; }
public bool Responded { get; set; }
public int Contact_RecID { get; set; }
public int Company_RecID { get; set; }
public string Survey_Qtr { get; set; }
public virtual Contact Contact { get; set; }
public virtual ICollection<SurveyResponseVM> SurveyResponse { get; set; }
}
Referenced SurveyResponseVM viewModel which is throwing the error:
public partial class SurveyResponseVM
{
public SurveyResponseVM()
{
this.Response_Values = new List<ValueData>();
}
public int Survey_Response_RecID { get; set; }
public int Survey_RecID { get; set; }
public int Survey_Question_RecID { get; set; }
public string Response { get; set; }
public Nullable<System.DateTime> Date_Responded { get; set; }
public int Contact_RecID { get; set; }
public int Company_RecID { get; set; }
public System.DateTime Date_Sent { get; set; }
public bool Responded { get; set; }
public string Survey_Qtr { get; set; }
public System.Guid Respondent_ID { get; set; }
public virtual Survey_Detail Survey_Detail { get; set; }
public virtual Survey_Question Survey_Question { get; set; }
public virtual ICollection<ValueData> Response_Values { get; set; }
public virtual Survey_Response_Header Survey_Response_Header { get; set; }
}
I know this means I'm not populating the ICollection part of the viewmodel correctly but I can't seem to figure out how it's supposed to be done. I've done days of research on the internet and I either don't know the right question to ask or I'm completely missing it. Any help you can give me is VERY appreciated!
So the controller is essentially responsible for populating a model and pass this model to a view for rendering, there doesn't need to correspond to a database table.
The way I normally tackle this is to look at what the function is being performed, in this case survey and create a SurveyController. In here you will have a bunch of actions that correspond to views that are responsible for retrieving the correct data from the database, populating a model and then passing the model to the view for rendering.
So if you wanted to display a list of questions, you may do something like this (apologies if this contains errors, no VS atm):
public class SurveyController : Controller
{
public ActionResult Index()
{
var model = new SurveyModel(); // This would contain any properties, like questions and their valid responses
return View(model);
}
}
public class SurveyModel
{
public IList<SurveyQuestionModel> Questions { get; set; }
}
I have got my application up and running using Code first, I am trying to set a 1-1 relationship but when I update-database I get the error "SupplyPointId: Name: Each property name in a type must be unique. Property name 'SupplyPointId' is already defined."
I've tried removing the existing index constraint on SupplyPointAddress.SupplyPointId and that does not help. In the other table its the PK. Any comments really appreciated
public partial class SupplyPoint
{
[Key]
//[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int SupplyPointId { get; set; }
public string SPID { get; set; }
public string SupplyPointName { get; set; }
public int SupplyPointTypeId { get; set; }
public DateTime SupplyPointEffectiveDateTime { get; set; }
public string GazateerRef { get; set; }
public virtual SupplyPointType SupplyPointType { get; set; }
//[ForeignKey("SupplyPointId")]
public virtual SupplyPointAddress SupplyPointAddress { get; set; }
}
public partial class SupplyPointAddress
{
[Key]
//[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int SupplyPointAddressId { get; set; }
public int SupplyPointId { get; set; }
public string D5001_FreeDescriptor { get; set; }
public string D5002_SubBuildingName { get; set; }
public string D5003_BuildingName { get; set; }
public string D5004_BuildingNumber { get; set; }
public string D5005_DependentThoroughfareName { get; set; }
public string D5006_DependentThoroughfareDescriptor { get; set; }
public string D5007_ThoroughfareName { get; set; }
public string D5008_ThoroughfareDescriptor { get; set; }
public string D5009_DoubleDependentLocality { get; set; }
public string D5010_DependentLocality { get; set; }
public string D5011_PostTown { get; set; }
public string D5012_County { get; set; }
public string D5013_Postcode { get; set; }
public virtual SupplyPoint SupplyPoint { get; set; }
}
public System.Data.Entity.DbSet<AscendancyCF.Models.SupplyPoint> SupplyPoints { get; set; }
public System.Data.Entity.DbSet<AscendancyCF.Models.SupplyPointAddress> SupplyPointAddresses { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<SupplyPointAddress>()
.HasOptional<SupplyPoint>(u => u.SupplyPoint)
.WithRequired(c => c.SupplyPointAddress).Map(p => p.MapKey("SupplyPointId"));
base.OnModelCreating(modelBuilder);
}
I moved the foreign key into SupplyPoint table so that the foreign key was being defined as SupplyPointAddressId in SupplyPoint. This worked and allows me to do SupplyPoint.SupplyPointAddress in resultant model
Since you're testing with a real DB. Use some of the
Database Initialization Strategies in Code-First:
public class SchoolDBContext: DbContext
{
public SchoolDBContext(): base("SchoolDBConnectionString")
{
Database.SetInitializer<SchoolDBContext>(new CreateDatabaseIfNotExists<SchoolDBContext>());
//Database.SetInitializer<SchoolDBContext>(new DropCreateDatabaseIfModelChanges<SchoolDBContext>());
//Database.SetInitializer<SchoolDBContext>(new DropCreateDatabaseAlways<SchoolDBContext>());
//Database.SetInitializer<SchoolDBContext>(new SchoolDBInitializer());
}
public DbSet<Student> Students { get; set; }
public DbSet<Standard> Standards { get; set; }
}
(Excerpt from this site)
It is pretty self explanatory.
If there's already a DB created, it just DROPs it.
Happy coding!