1

I have the following datamodel and its associated model classes. I have been removing dependencies to get it right, but I keep on getting this error.

Datamodel

Class diagram

I can't find out why there is a cascading path in the model. I am afraid I will not be able to reduce the dependencies.

Model Classes

public class DataFormat
{
    public int DataFormatID { get; set; }
    [Display (Name = "Data Format Name")]
    [Remote("DuplicateFormatName", "DataFormats", HttpMethod = "POST", ErrorMessage = "Data Format Name already Exists")]
    public string FormatName { get; set; }
    [Display (Name = "Data Format Type")]
    public string FormatType { get; set; }
    [Display (Name = "Precision Digits")]
    public string PrecisionDigits { get; set; }
    [Display (Name = "Scaling Digits")]
    public string ScalingDigits { get; set; }
    [Display (Name = "Description in German")]
    public string DescriptionDE { get; set; }
    [Display (Name = "Description in English")]
    public string DescriptionEN { get; set; }
    public DateTime CreatedOn { get; set; }
    public DateTime ModifiedOn { get; set; }
    public string CreatedBy { get; set;}
    public string ModifiedBy { get; set; }

    public virtual ICollection<TcSet> TcSets { get; set; }
}

public class Lsystem
{
    public int LsystemID { get; set; }
    [Display (Name = "System Name") ]
    [Remote("DuplicateSystemName", "Lsystems", HttpMethod = "POST", ErrorMessage = "System Name already Exists")]
    public string LsystemName { get; set; }
    [Display (Name = "Material Number")]
    public string MaterialNumber { get; set; }
    public DateTime CreatedOn { get; set; }
    public DateTime ModifiedOn { get; set; }
    public string CreatedBy { get; set; }
    public string ModifiedBy { get; set; }
    [Display(Name = "Description in English")]
    public string DescriptionEN { get; set; }
    [Display(Name = "Description in German")]
    public string DescriptionDE { get; set; }

    public int LsystemFamilyID { get; set; }

    public virtual LsystemFamily LsystemFamily { get; set; }
    public virtual ICollection<Option> Options { get; set; }
}

public class LsystemFamily
{
    public int LsystemFamilyID { get; set; }
    [Display (Name = "Family Name")]
    [Remote("DuplicateFamilyName","LsystemFamilies",HttpMethod = "POST",ErrorMessage= "System Family Name already Exists")]
    public string FamilyName { get; set; }
    public int LsystemCount { get; set; }
    [Display ( Name = "Description in English")]
    public string DescriptionEN { get; set; }
    [Display (Name = "Description in German")]
    public string DescriptionDE { get; set; }
    public DateTime CreatedOn { get; set; }
    public DateTime ModifiedOn { get; set; }
    public string CreatedBy { get; set; }
    public string ModifiedBy { get; set; }

    public virtual ICollection<Lsystem> Lsystems { get; set; }
}

public class Option
{
    public int OptionID { get; set;}
    [Display (Name = "Option Type")]
    public string OptionName { get; set; }
    [Display (Name ="Description in English")]
    public string DescriptionEN { get; set; }
    [Display(Name = "Description in German")]
    public string DescriptionDE { get; set; }
    public DateTime CreatedOn { get; set; }
    public DateTime ModifiedOn { get; set; }
    public string CreatedBy { get; set; }
    public string ModifiedBy { get; set; }

    public int TechnicalCharacteristicID { get; set; }
    public int LsystemID { get; set; }

    public virtual ICollection<OptionValue> OptionValues { get; set; }
    public virtual TechnicalCharacteristic TechnicalCharacteristic { get; set; }
    public virtual Lsystem Lsystem { get; set; }
   // public virtual ICollection< SetValue> SetValue { get; set; }
}

public class OptionValue
{
    public int OptionValueID { get; set; }
    [Display(Name = "Option Value")]
    public string OptionVal { get; set; }

    public int OptionID { get; set; }
   // public int SetValueID { get; set; }

    public virtual Option Option { get; set; }
    public virtual ICollection< SetValue> SetValue { get; set; }
}

public class SetValue
{
    public int SetValueID { get; set; }
    [Display(Name = "Value")]
    public string Value { get; set; }
    [Display(Name="Internal")]
    public bool Status { get; set; }

    //public int LsystemID { get; set; }
    //public int OptionID { get; set; }
    public int TcSetID { get; set; }
    public int OptionValueID { get; set; }

    //public virtual Lsystem Lsystem { get; set; }
    //public virtual Option Option { get; set; }
    public virtual OptionValue OptionValue { get; set; }
    public virtual TcSet TcSet { get; set; }

}

public class TcSet
{
    public int TcSetID { get; set; }
    [Display (Name = "Technical characteristic Property name")]
    public string SetName { get; set; }
    [Display(Name = "PhysicalUnit")]
    public string PhysicalUnit { get; set; }
    [Display (Name = "Data Usage")]
    public DataUsage DataUsage { get; set; }
    [Display (Name = "Data Status")]
    public DataStatus DataStatus { get; set; }
    public DateTime CreatedOn { get; set; }
    public DateTime ModifiedOn { get; set; }
    [Display (Name = "Description in German")]
    public string DescriptionDE { get; set; }
    [Display (Name = "Description in English")]
    public string DescriptionEN { get; set; }
    public string CreatedBy { get; set; }
    public string ModifiedBy { get; set; }

    public int TechnicalCharacteristicID { get; set; }
    public int DataFormatID { get; set; }

    public virtual ICollection<SetValue> SetValues { get; set; }
    public virtual DataFormat DataFormat { get; set; }
    public virtual TechnicalCharacteristic TechnicalCharacteristic { get; set; }
}

public class TechnicalCharacteristic
{
    public int TechnicalCharacteristicID { get; set; }
    [Display (Name = "Technical Characteristic Name")]
    public string TCName { get; set; }
    [Display (Name = "Description in English")]
    public string DescriptionEN { get; set; }
    [Display (Name = "Description in German")]
    public string DescriptionDE { get; set; }
    public DateTime CreatedOn { get; set; }
    public DateTime ModifiedOn { get; set; }
    public string CreatedBy { get; set; }
    public string ModifiedBy { get; set; }

    public virtual ICollection<TcSet> TcSets { get; set; }
    //public virtual ICollection<Option> Options { get; set; }
}

Now my error is between the tables Options and technicalCharacteristics. I had the error previosly with LSystem and SetVal & Options.

What can be the workaround to get the task right? I have not tried fluent APIs.

Vini
  • 1,978
  • 8
  • 40
  • 82
  • imho, the `public virtual TechnicalCharacteristic TechnicalCharacteristic { get; set; }` of the Option class is enough to establish the cycle. Commenting `public virtual ICollection – tschmit007 Sep 30 '15 at 15:34
  • Have you read http://stackoverflow.com/questions/29062094/entity-framework-code-first-cycles-or-multiple-cascade-paths – tschmit007 Sep 30 '15 at 15:36
  • @tschmit007: If you dont mind can you tell me why `public virtual TechnicalCharacteristic TechnicalCharacteristic { get; set; } ` establishes a cycle? – Vini Oct 01 '15 at 05:21
  • And the `TechnicalCharacteristic` stand as an independent entity but used by the `Options`. How is the dependency making it cyclic. Maybe the reason is I have not very well understood the concept of multiple paths in the right way. – Vini Oct 01 '15 at 05:23
  • Imagine you want to serialize a `System`, then in some condition you may have an infintite loop: TechnicalCaracteristic -> Option. I'm talking of cycles, for the path, please refer to cited post. – tschmit007 Oct 01 '15 at 08:34
  • I have checked the post mentioned, but my understanding from the post was so minimum. – Vini Oct 01 '15 at 08:42
  • It basically tells you that you have to add mappings containing `WillCascadeOnDelete(false)` calls. – Gert Arnold Oct 04 '15 at 09:16
  • @GertArnold: So can i add the cascade on delete and then fluent APIs to show the mapping? Will that work ? – Vini Oct 05 '15 at 05:16

2 Answers2

1

Here is another way you can do the same AND have a technicalChareristic to be required. I did this last week with one of my own models. Sorry it toook so long to come up with a reply. (Do the same with the other files.)

In your Context file override the following method...

  protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Option>()
            .HasRequired(x => x.TechnicalCharacteristic)
            .WithMany(y => y.Options)
            .HasForeignKey(a => a.TechnicalCharacteristicID)
            .WillCascadeOnDelete(false);

        base.OnModelCreating(modelBuilder);
    }

Where the models are...

public class Option
{
    public int OptionID { get; set; }
    [Display(Name = "Option Type")]
    public string OptionName { get; set; }
    [Display(Name = "Description in English")]
    public string DescriptionEN { get; set; }
    [Display(Name = "Description in German")]
    public string DescriptionDE { get; set; }
    public DateTime CreatedOn { get; set; }
    public DateTime ModifiedOn { get; set; }
    public string CreatedBy { get; set; }
    public string ModifiedBy { get; set; }

    public int LsystemID { get; set; }

    public virtual ICollection<OptionValue> OptionValues { get; set; }

    public int TechnicalCharacteristicID { get; set; }
    public virtual TechnicalCharacteristic TechnicalCharacteristic { get; set; }
    public virtual Lsystem Lsystem { get; set; }
    // public virtual ICollection< SetValue> SetValue { get; set; }

    DateTime d = new DateTime();
}


public class TechnicalCharacteristic
{
    public int TechnicalCharacteristicID { get; set; }
    [Display(Name = "Technical Characteristic Name")]
    public string TCName { get; set; }
    [Display(Name = "Description in English")]
    public string DescriptionEN { get; set; }
    [Display(Name = "Description in German")]
    public string DescriptionDE { get; set; }
    public DateTime CreatedOn { get; set; }
    public DateTime ModifiedOn { get; set; }
    public string CreatedBy { get; set; }
    public string ModifiedBy { get; set; }

    public virtual ICollection<TcSet> TcSets { get; set; }
    public virtual ICollection<Option> Options { get; set; }

}

I hope this helps.

alikuli
  • 526
  • 6
  • 18
  • Thanks for the comment. I have removed the cascading deletes as a whole and none of my Delete functions where working. So i coded the deletion of the child classes in the parent class and now it works fine. But i think your answer is what i was looking for. – Vini Oct 21 '15 at 05:18
0

I believe your error is coming because EntityFramework cannot handle the null state of your TechnicalCharacteristicID in the Option class. If you have no problem in TechnicalCharacteristic being null, do the following in your option class. It should get rid of your error:

        public int? TechnicalCharacteristicID { get; set; }

that is, your option class will become...

public class Option
{
    public int OptionID { get; set; }
    [Display(Name = "Option Type")]
    public string OptionName { get; set; }
    [Display(Name = "Description in English")]
    public string DescriptionEN { get; set; }
    [Display(Name = "Description in German")]
    public string DescriptionDE { get; set; }
    public DateTime CreatedOn { get; set; }
    public DateTime ModifiedOn { get; set; }
    public string CreatedBy { get; set; }
    public string ModifiedBy { get; set; }

    public int LsystemID { get; set; }

    public virtual ICollection<OptionValue> OptionValues { get; set; }

    public int? TechnicalCharacteristicID { get; set; }
    public virtual TechnicalCharacteristic TechnicalCharacteristic { get; set; }
    public virtual Lsystem Lsystem { get; set; }
    // public virtual ICollection< SetValue> SetValue { get; set; }
}

Do the same with other errant tables. I hope this answers your question! Good luck.

alikuli
  • 526
  • 6
  • 18
  • No, it's a SQL Server exception (and restriction). It's not about anything EF can't handle. – Gert Arnold Oct 04 '15 at 09:14
  • @alikuli : but i cant make the technicalcharacteristic to be null. it can sand as a stand alone entity. but an option is not required for a particular technicalcharacteristic. but i suppose i have made it that way. – Vini Oct 04 '15 at 09:51
  • If you can have an option without a technical characteristic... then you can use this. If you need the technical characteristic to be required, you can do it through code, i.e. ensure that it is present. – alikuli Oct 04 '15 at 10:35