0

I'm new to Entity Framework and I've run into some problems while trying to implement my ERD Code First. The situation is as follows:

ERD

A product has a group of questions (QuestionGroup). A QuestionGroup has multiple questions and can belong to multiple Questionaires. A Questionaire basically has a questiongroup and a questionorder. The questionorder is supposed to keep the position of a question within that questionaire. The Questionaire table is needed because a QuestionGroup can have multiple questionorders, and a questionorder can belong to multiple questiongroups.

Because I'm trying my best to keep this post succinct I won't post all my classes, unless you ask to see them. The Entity classes I've made look like this:

public class Question
    {
        [Key]
        public int Id { get; set; }

        [MaxLength(2000)]
        [Required]
        public string Text { get; set; }
        public Answer Answer { get; set; }
        public QuestionType Type { get; set; }
        public ICollection<QuestionAnswerOption> Options { get; set; }
        public ICollection<QuestionOrder> Orders { get; set; }

        [ForeignKey("FollowupQuestion")]
        public int QuestionId { get; set; }
        public virtual Question FollowupQuestion { get; set; }
        [ForeignKey("Questiongroup")]
        public int QuestionGroupId { get; set; }
        public virtual QuestionGroup Questiongroup { get; set; }

    }

public class QuestionOrder
    {
        [Key]
        public int Id { get; set; }

        public int Position { get; set; }

        [ForeignKey("Question")]
        [Required]
        public int QuestionId { get; set; }
        public virtual Question Question { get; set; }
        [ForeignKey("Questionaire")]
        [Required]
        public int QuestionaireId { get; set; }
        public virtual Questionaire Questionaire { get; set; }

    }

  public class Product
    {
        [Key]
        public int Id { get; set; }

        [MaxLength(150)]
        [Required]
        [Index(IsUnique = true)]
        public string Name { get; set; }
        [MaxLength(500)]
        public string Summary { get; set; }
        [MaxLength(500)]
        public string Examples { get; set; }
        public virtual QuestionGroup QuestionGroup { get; set; }
    }

public class QuestionGroup
    {
        [Key]
        public int Id { get; set; }

        public ICollection<Question> Questions { get; set; }

        [ForeignKey("Product")]
        public int ProductId { get; set; }
        public virtual Product Product { get; set; }

    }

 public class Questionaire
    {
        [Key]
        public int Id { get; set; }

        public QuestionGroup Group { get; set; }

        public QuestionOrder Order { get; set; }
    }

The errors I'm getting look like this:

QuestionGroup_Product_Source: : Multiplicity is not valid in Role 'QuestionGroup_Product_Source' in relationship 'QuestionGroup_Product'. Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be '*'.

QuestionOrder_Questionaire_Source: : Multiplicity is not valid in Role 'QuestionOrder_Questionaire_Source' in relationship 'QuestionOrder_Questionaire'. Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be '*'.

QuestionType_Question_Source: : Multiplicity is not valid in Role 'QuestionType_Question_Source' in relationship 'QuestionType_Question'. Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be '*'.

The question we've arrived at here is: Does anyone here know of a way to fix the relations between my tables? Maybe my ERD needs some improvements too, but I think the problem is that I'm missing a few things with my Code First implementation.

Flippey
  • 91
  • 1
  • 8
  • Do you have any additional entity configuration? For example, using the Fluent API? – Vlad274 Oct 09 '15 at 13:59
  • No, I do not. I'm not sure how that works. – Flippey Oct 09 '15 at 14:00
  • Missing the definition for Product and Questionaire. Not 100% sure, but it might be choking on the fact that your FK property names are not the same as the Key property names. I know this will look goofy, but rename Id in Question to QuestionId and see if any errors go away. if so, you know this may be part of the issue. As for how to handle FollowupQuestion, I'm not sure how EF handles this. –  Oct 09 '15 at 14:27
  • Also, http://stackoverflow.com/questions/1761362/entity-framework-one-to-one-mapping-issues http://stackoverflow.com/questions/19276381/multiplicity-not-allowed-entity-framework http://stackoverflow.com/questions/9888105/asp-net-mvc-code-first-multiplicity-is-not-valid-in-role-in-relationship –  Oct 09 '15 at 14:30
  • Renamed Id in Question to QuestionId, didn't solve anything – Flippey Oct 09 '15 at 14:36

1 Answers1

0

what about this design for you;)

public class Customer
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int CustomerId { get; set; }
    public string CompanyName { get; set; }

    public virtual ICollection<ContactInfo> ContactInfoes { get; set; }
    public virtual ICollection<ProductQuestionaireReport> Reports { get; set; }
}
public class ContactInfo
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Key]
    public int ContactInfoId { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public int Telephone { get; set; }

    [ForeignKey("Customer")]
    public int CustomerId { get; set; }
    public virtual Customer Customer { get; set; }
}
public class ProductQuestionaireReport
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ProductQuestionaireReportId { get; set; }

    [ForeignKey("Product")]
    public int ProductId { get; set; }
    public virtual Product Product { get; set; }

    public virtual QuestionaireResult Result { get; set; }

    [ForeignKey("Customer")]
    public int CustomerId { get; set; }
    public virtual Customer Customer { get; set; }

    public bool Haste { get; set; }
    public string Status { get; set; }
    public string Comment { get; set; }
}
public class QuestionaireResult
{
    [Key, ForeignKey("ProductQuestionaireReport")]
    public int ProductQuestionaireReportId { get; set; }

    [ForeignKey("Questionaire")]
    public int QuestionaireId { get; set; }
    public virtual Questionaire Questionaire { get; set; }

    public DateTime SurveyCreated { get; set; }
    public Double Costs { get; set; }
    public Double FunctionPoints { get; set; }

    public virtual ProductQuestionaireReport ProductQuestionaireReport { get; set; }
    public virtual ICollection<QuestionaireAnswer> Answers { get; set; }
}
public class Product
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ProductId { get; set; }
    public string Name { get; set; }
    public string Summary { get; set; }
    public string Examples { get; set; }

    public virtual ICollection<Questionaire> Questionaires { get; set; }
    public virtual ICollection<ProductQuestionaireReport> Reports { get; set; }
}
public class QuestionaireAnswer
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int QuestionaireAnswerId { get; set; }

    [ForeignKey("QuestionaireResult")]
    public int QuestionaireResultId { get; set; }
    public virtual QuestionaireResult QuestionaireResult { get; set; }

    [ForeignKey("QuestionaireQuestion")]
    public int QuestionaireId { get; set; }
    public virtual QuestionaireQuestion QuestionaireQuestion { get; set; }

    [ForeignKey("Answer")]
    public int AnswerId { get; set; }
    public virtual QuestionOption Answer { get; set; }

    public string Text { get; set; }
    public virtual ICollection<string> Files { get; set; }
}
public class Questionaire
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int QuestionaireId { get; set; }
    [ForeignKey("Product")]
    public int ProductId { get; set; }
    public virtual Product Product { get; set; }

    public virtual ICollection<QuestionaireQuestion> QuestionaireQuestions { get; set; }
    public virtual ICollection<QuestionaireResult> Results { get; set; }
}
public class Question
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int QuestionId { get; set; }

    [ForeignKey("ParentQuestion")]
    public int ParentQuestionId { get; set; }
    public virtual Question ParentQuestion { get; set; }

    public virtual QuestionType QuestionType { get; set; }
    public virtual ICollection<QuestionOption> Options { get; set; }
}
public class QuestionType
{
    [Key, ForeignKey("Question")]
    public int QuestionId { get; set; }

    public string Text { get; set; }
    public bool IsOpenQuestion { get; set; }

    public virtual Question Question { get; set; }
}
public class QuestionOption
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int QuestionAnswerOptionId { get; set; }

    [ForeignKey("Question")]
    public int QuestionId { get; set; }
    public string Text { get; set; }

    public virtual Question Question { get; set; }
}
public class QuestionaireQuestion
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int QuestionaireQuestionId { get; set; }

    [ForeignKey("Questionaire")]
    public int QuestionaireId { get; set; }
    public virtual Questionaire Questionaire { get; set; }

    [ForeignKey("Question")]
    public int QuestionId { get; set; }
    public int DisplayOrder { get; set; }

    public virtual Question Question { get; set; }
}

also you must add this to OnModelCreating

modelBuilder.Entity<Customer>().HasMany(c => c.ContactInfoes)
    .WithRequired(i => i.Customer).HasForeignKey(i => i.CustomerId).WillCascadeOnDelete(false);

modelBuilder.Entity<Question>().HasMany(q => q.Options)
    .WithRequired(o => o.Question).HasForeignKey(o => o.QuestionId).WillCascadeOnDelete(false);

modelBuilder.Entity<QuestionaireResult>().HasMany(r => r.Answers)
    .WithRequired(a => a.QuestionaireResult).HasForeignKey(o => o.QuestionaireResultId).WillCascadeOnDelete(false);

check it and feedback me ...

Sherif Ahmed
  • 1,896
  • 1
  • 19
  • 37