Circular reference with Classes/Database (C#, Entity Framework Code First)












1














Is there a better design, when no circular referece occurs? Is it a problem at all?
The Classes:



public class Stat
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }

public List<Quantity> Quantities { get; set; }
public List<Hit> Hits { get; set; }
}
public class Hit
{
public int Id { get; set; }
public DateTime Date { get; set; }
public string Comment { get; set; }

public virtual Stat Stat { get; set; }
public List<HitComponent> HitComponents { get; set; }
}
public class HitComponent
{
public int Id { get; set; }
public float Amount { get; set; }

public virtual Hit Hit { get; set; }
public virtual Quantity Quantity { get; set; }
}
public class Quantity
{
public int Id { get; set; }
public string Name { get; set; }

public virtual Stat Stat { get; set; }
public virtual Unit Unit { get; set; }
public List<HitComponent> HitComponents { get; set; }
}
public class Unit
{
public int Id { get; set; }
public string Name { get; set; }
public string Abbreviation { get; set; }

public List<Quantity> Quantities { get; set; }
}


Class diagram
A Stat is for a statistics of something, for example a training exercise like weight lifting. A Quantity can be something that can be measured with a number, for example the weight of the barbell used (in kilograms - the unit is stored in the Unit class), or the number of repeats. In this case the Stat (weight lifting) has two Quantities (weight, reps). A Hit is one event of a Stat (a weight lifting training done once). A HitComponent belongs to a Hit, and it contains the amount of one Quantity. Every Hit must contain as much HitComponent, as much Quantities a Hit's Stat has. (For example every "weight lifting" Stat's Hit must contain two HitComponents, one for the "weight" Quantity, one for the "reps" Quantity. I suspect, that maybe this prerequisite can cause some problem...)



I use the design shown above, and there weren't too much problems - just a bit awkward with the circular reference - as long as I wanted to serialize some classes to Json string, because it caused circular reference exception.



My first question is that there is any problem with this design at all? I googled a lot, and didn't find a clear and defined answer to this kind of circular reference (some say it is not a real circular reference, because the direction is not "circular", others say that this solution is very problematic)?
The other question is that somebody can suggest a better design?










share|improve this question





























    1














    Is there a better design, when no circular referece occurs? Is it a problem at all?
    The Classes:



    public class Stat
    {
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }

    public List<Quantity> Quantities { get; set; }
    public List<Hit> Hits { get; set; }
    }
    public class Hit
    {
    public int Id { get; set; }
    public DateTime Date { get; set; }
    public string Comment { get; set; }

    public virtual Stat Stat { get; set; }
    public List<HitComponent> HitComponents { get; set; }
    }
    public class HitComponent
    {
    public int Id { get; set; }
    public float Amount { get; set; }

    public virtual Hit Hit { get; set; }
    public virtual Quantity Quantity { get; set; }
    }
    public class Quantity
    {
    public int Id { get; set; }
    public string Name { get; set; }

    public virtual Stat Stat { get; set; }
    public virtual Unit Unit { get; set; }
    public List<HitComponent> HitComponents { get; set; }
    }
    public class Unit
    {
    public int Id { get; set; }
    public string Name { get; set; }
    public string Abbreviation { get; set; }

    public List<Quantity> Quantities { get; set; }
    }


    Class diagram
    A Stat is for a statistics of something, for example a training exercise like weight lifting. A Quantity can be something that can be measured with a number, for example the weight of the barbell used (in kilograms - the unit is stored in the Unit class), or the number of repeats. In this case the Stat (weight lifting) has two Quantities (weight, reps). A Hit is one event of a Stat (a weight lifting training done once). A HitComponent belongs to a Hit, and it contains the amount of one Quantity. Every Hit must contain as much HitComponent, as much Quantities a Hit's Stat has. (For example every "weight lifting" Stat's Hit must contain two HitComponents, one for the "weight" Quantity, one for the "reps" Quantity. I suspect, that maybe this prerequisite can cause some problem...)



    I use the design shown above, and there weren't too much problems - just a bit awkward with the circular reference - as long as I wanted to serialize some classes to Json string, because it caused circular reference exception.



    My first question is that there is any problem with this design at all? I googled a lot, and didn't find a clear and defined answer to this kind of circular reference (some say it is not a real circular reference, because the direction is not "circular", others say that this solution is very problematic)?
    The other question is that somebody can suggest a better design?










    share|improve this question



























      1












      1








      1







      Is there a better design, when no circular referece occurs? Is it a problem at all?
      The Classes:



      public class Stat
      {
      public int Id { get; set; }
      public string Name { get; set; }
      public string Description { get; set; }

      public List<Quantity> Quantities { get; set; }
      public List<Hit> Hits { get; set; }
      }
      public class Hit
      {
      public int Id { get; set; }
      public DateTime Date { get; set; }
      public string Comment { get; set; }

      public virtual Stat Stat { get; set; }
      public List<HitComponent> HitComponents { get; set; }
      }
      public class HitComponent
      {
      public int Id { get; set; }
      public float Amount { get; set; }

      public virtual Hit Hit { get; set; }
      public virtual Quantity Quantity { get; set; }
      }
      public class Quantity
      {
      public int Id { get; set; }
      public string Name { get; set; }

      public virtual Stat Stat { get; set; }
      public virtual Unit Unit { get; set; }
      public List<HitComponent> HitComponents { get; set; }
      }
      public class Unit
      {
      public int Id { get; set; }
      public string Name { get; set; }
      public string Abbreviation { get; set; }

      public List<Quantity> Quantities { get; set; }
      }


      Class diagram
      A Stat is for a statistics of something, for example a training exercise like weight lifting. A Quantity can be something that can be measured with a number, for example the weight of the barbell used (in kilograms - the unit is stored in the Unit class), or the number of repeats. In this case the Stat (weight lifting) has two Quantities (weight, reps). A Hit is one event of a Stat (a weight lifting training done once). A HitComponent belongs to a Hit, and it contains the amount of one Quantity. Every Hit must contain as much HitComponent, as much Quantities a Hit's Stat has. (For example every "weight lifting" Stat's Hit must contain two HitComponents, one for the "weight" Quantity, one for the "reps" Quantity. I suspect, that maybe this prerequisite can cause some problem...)



      I use the design shown above, and there weren't too much problems - just a bit awkward with the circular reference - as long as I wanted to serialize some classes to Json string, because it caused circular reference exception.



      My first question is that there is any problem with this design at all? I googled a lot, and didn't find a clear and defined answer to this kind of circular reference (some say it is not a real circular reference, because the direction is not "circular", others say that this solution is very problematic)?
      The other question is that somebody can suggest a better design?










      share|improve this question















      Is there a better design, when no circular referece occurs? Is it a problem at all?
      The Classes:



      public class Stat
      {
      public int Id { get; set; }
      public string Name { get; set; }
      public string Description { get; set; }

      public List<Quantity> Quantities { get; set; }
      public List<Hit> Hits { get; set; }
      }
      public class Hit
      {
      public int Id { get; set; }
      public DateTime Date { get; set; }
      public string Comment { get; set; }

      public virtual Stat Stat { get; set; }
      public List<HitComponent> HitComponents { get; set; }
      }
      public class HitComponent
      {
      public int Id { get; set; }
      public float Amount { get; set; }

      public virtual Hit Hit { get; set; }
      public virtual Quantity Quantity { get; set; }
      }
      public class Quantity
      {
      public int Id { get; set; }
      public string Name { get; set; }

      public virtual Stat Stat { get; set; }
      public virtual Unit Unit { get; set; }
      public List<HitComponent> HitComponents { get; set; }
      }
      public class Unit
      {
      public int Id { get; set; }
      public string Name { get; set; }
      public string Abbreviation { get; set; }

      public List<Quantity> Quantities { get; set; }
      }


      Class diagram
      A Stat is for a statistics of something, for example a training exercise like weight lifting. A Quantity can be something that can be measured with a number, for example the weight of the barbell used (in kilograms - the unit is stored in the Unit class), or the number of repeats. In this case the Stat (weight lifting) has two Quantities (weight, reps). A Hit is one event of a Stat (a weight lifting training done once). A HitComponent belongs to a Hit, and it contains the amount of one Quantity. Every Hit must contain as much HitComponent, as much Quantities a Hit's Stat has. (For example every "weight lifting" Stat's Hit must contain two HitComponents, one for the "weight" Quantity, one for the "reps" Quantity. I suspect, that maybe this prerequisite can cause some problem...)



      I use the design shown above, and there weren't too much problems - just a bit awkward with the circular reference - as long as I wanted to serialize some classes to Json string, because it caused circular reference exception.



      My first question is that there is any problem with this design at all? I googled a lot, and didn't find a clear and defined answer to this kind of circular reference (some say it is not a real circular reference, because the direction is not "circular", others say that this solution is very problematic)?
      The other question is that somebody can suggest a better design?







      c# entity-framework database-design ef-code-first circular-reference






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 19 '18 at 16:37









      Cœur

      17.4k9103145




      17.4k9103145










      asked Aug 31 '13 at 17:23









      Csati

      5871925




      5871925
























          1 Answer
          1






          active

          oldest

          votes


















          0














          Circular references aren't so evil. If you look, your references are just virtual (your List should also be virtual) so really it is more along the lines of reserving the ability to follow a reference in either direction. That this creates a "circular reference" by EF's definition or by design is just a side affect.



          The only time you are going to have issues with these circular references is when you try to serialize an object which contains both navigation properties. In this case, you will have to instruct the serializer to skip one of the navigation directions in order to remove the circular reference.



          Depending on the serializer, ignoring the navigation properties will be done differently. With the vanilla serializer (JavaScriptSerializer) which is used when Json(var) is used, you can use the [ScriptIgnore] attribute on your properties which you wish not to be followed during serialization.



          For example, to remove the circular reference from Stat to Hit



          public class Stat
          {
          public int Id { get; set; }
          public string Name { get; set; }
          public string Description { get; set; }

          public virtual List<Quantity> Quantities { get; set; }
          [ScriptIgnore]
          public virtual List<Hit> Hits { get; set; }
          }





          share|improve this answer





















          • Good solution, works for me. However I'm a bit still confused about circular references (or dependencies - what's the difference...?). In my case there is a prerequisite that if a Stat has for example 3 Quantities then when one HitComponent is inserted to one Quantity, the other 2 Quantities must have 1-1 HitComponents, too. Is it a good practice that this prerequisite appears in the design of classes/database tables? Or is it better to take care of this rule in the program logic, and have a cleaner design free of circular references - e.g. with removing the reference between Stats and Hits?
            – Csati
            Sep 1 '13 at 10:04













          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f18550845%2fcircular-reference-with-classes-database-c-entity-framework-code-first%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          0














          Circular references aren't so evil. If you look, your references are just virtual (your List should also be virtual) so really it is more along the lines of reserving the ability to follow a reference in either direction. That this creates a "circular reference" by EF's definition or by design is just a side affect.



          The only time you are going to have issues with these circular references is when you try to serialize an object which contains both navigation properties. In this case, you will have to instruct the serializer to skip one of the navigation directions in order to remove the circular reference.



          Depending on the serializer, ignoring the navigation properties will be done differently. With the vanilla serializer (JavaScriptSerializer) which is used when Json(var) is used, you can use the [ScriptIgnore] attribute on your properties which you wish not to be followed during serialization.



          For example, to remove the circular reference from Stat to Hit



          public class Stat
          {
          public int Id { get; set; }
          public string Name { get; set; }
          public string Description { get; set; }

          public virtual List<Quantity> Quantities { get; set; }
          [ScriptIgnore]
          public virtual List<Hit> Hits { get; set; }
          }





          share|improve this answer





















          • Good solution, works for me. However I'm a bit still confused about circular references (or dependencies - what's the difference...?). In my case there is a prerequisite that if a Stat has for example 3 Quantities then when one HitComponent is inserted to one Quantity, the other 2 Quantities must have 1-1 HitComponents, too. Is it a good practice that this prerequisite appears in the design of classes/database tables? Or is it better to take care of this rule in the program logic, and have a cleaner design free of circular references - e.g. with removing the reference between Stats and Hits?
            – Csati
            Sep 1 '13 at 10:04


















          0














          Circular references aren't so evil. If you look, your references are just virtual (your List should also be virtual) so really it is more along the lines of reserving the ability to follow a reference in either direction. That this creates a "circular reference" by EF's definition or by design is just a side affect.



          The only time you are going to have issues with these circular references is when you try to serialize an object which contains both navigation properties. In this case, you will have to instruct the serializer to skip one of the navigation directions in order to remove the circular reference.



          Depending on the serializer, ignoring the navigation properties will be done differently. With the vanilla serializer (JavaScriptSerializer) which is used when Json(var) is used, you can use the [ScriptIgnore] attribute on your properties which you wish not to be followed during serialization.



          For example, to remove the circular reference from Stat to Hit



          public class Stat
          {
          public int Id { get; set; }
          public string Name { get; set; }
          public string Description { get; set; }

          public virtual List<Quantity> Quantities { get; set; }
          [ScriptIgnore]
          public virtual List<Hit> Hits { get; set; }
          }





          share|improve this answer





















          • Good solution, works for me. However I'm a bit still confused about circular references (or dependencies - what's the difference...?). In my case there is a prerequisite that if a Stat has for example 3 Quantities then when one HitComponent is inserted to one Quantity, the other 2 Quantities must have 1-1 HitComponents, too. Is it a good practice that this prerequisite appears in the design of classes/database tables? Or is it better to take care of this rule in the program logic, and have a cleaner design free of circular references - e.g. with removing the reference between Stats and Hits?
            – Csati
            Sep 1 '13 at 10:04
















          0












          0








          0






          Circular references aren't so evil. If you look, your references are just virtual (your List should also be virtual) so really it is more along the lines of reserving the ability to follow a reference in either direction. That this creates a "circular reference" by EF's definition or by design is just a side affect.



          The only time you are going to have issues with these circular references is when you try to serialize an object which contains both navigation properties. In this case, you will have to instruct the serializer to skip one of the navigation directions in order to remove the circular reference.



          Depending on the serializer, ignoring the navigation properties will be done differently. With the vanilla serializer (JavaScriptSerializer) which is used when Json(var) is used, you can use the [ScriptIgnore] attribute on your properties which you wish not to be followed during serialization.



          For example, to remove the circular reference from Stat to Hit



          public class Stat
          {
          public int Id { get; set; }
          public string Name { get; set; }
          public string Description { get; set; }

          public virtual List<Quantity> Quantities { get; set; }
          [ScriptIgnore]
          public virtual List<Hit> Hits { get; set; }
          }





          share|improve this answer












          Circular references aren't so evil. If you look, your references are just virtual (your List should also be virtual) so really it is more along the lines of reserving the ability to follow a reference in either direction. That this creates a "circular reference" by EF's definition or by design is just a side affect.



          The only time you are going to have issues with these circular references is when you try to serialize an object which contains both navigation properties. In this case, you will have to instruct the serializer to skip one of the navigation directions in order to remove the circular reference.



          Depending on the serializer, ignoring the navigation properties will be done differently. With the vanilla serializer (JavaScriptSerializer) which is used when Json(var) is used, you can use the [ScriptIgnore] attribute on your properties which you wish not to be followed during serialization.



          For example, to remove the circular reference from Stat to Hit



          public class Stat
          {
          public int Id { get; set; }
          public string Name { get; set; }
          public string Description { get; set; }

          public virtual List<Quantity> Quantities { get; set; }
          [ScriptIgnore]
          public virtual List<Hit> Hits { get; set; }
          }






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Aug 31 '13 at 17:30









          Travis J

          63.8k28148223




          63.8k28148223












          • Good solution, works for me. However I'm a bit still confused about circular references (or dependencies - what's the difference...?). In my case there is a prerequisite that if a Stat has for example 3 Quantities then when one HitComponent is inserted to one Quantity, the other 2 Quantities must have 1-1 HitComponents, too. Is it a good practice that this prerequisite appears in the design of classes/database tables? Or is it better to take care of this rule in the program logic, and have a cleaner design free of circular references - e.g. with removing the reference between Stats and Hits?
            – Csati
            Sep 1 '13 at 10:04




















          • Good solution, works for me. However I'm a bit still confused about circular references (or dependencies - what's the difference...?). In my case there is a prerequisite that if a Stat has for example 3 Quantities then when one HitComponent is inserted to one Quantity, the other 2 Quantities must have 1-1 HitComponents, too. Is it a good practice that this prerequisite appears in the design of classes/database tables? Or is it better to take care of this rule in the program logic, and have a cleaner design free of circular references - e.g. with removing the reference between Stats and Hits?
            – Csati
            Sep 1 '13 at 10:04


















          Good solution, works for me. However I'm a bit still confused about circular references (or dependencies - what's the difference...?). In my case there is a prerequisite that if a Stat has for example 3 Quantities then when one HitComponent is inserted to one Quantity, the other 2 Quantities must have 1-1 HitComponents, too. Is it a good practice that this prerequisite appears in the design of classes/database tables? Or is it better to take care of this rule in the program logic, and have a cleaner design free of circular references - e.g. with removing the reference between Stats and Hits?
          – Csati
          Sep 1 '13 at 10:04






          Good solution, works for me. However I'm a bit still confused about circular references (or dependencies - what's the difference...?). In my case there is a prerequisite that if a Stat has for example 3 Quantities then when one HitComponent is inserted to one Quantity, the other 2 Quantities must have 1-1 HitComponents, too. Is it a good practice that this prerequisite appears in the design of classes/database tables? Or is it better to take care of this rule in the program logic, and have a cleaner design free of circular references - e.g. with removing the reference between Stats and Hits?
          – Csati
          Sep 1 '13 at 10:04




















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f18550845%2fcircular-reference-with-classes-database-c-entity-framework-code-first%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          MongoDB - Not Authorized To Execute Command

          in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith

          Npm cannot find a required file even through it is in the searched directory