Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. What is the correct way to do Business Validation on entities?

What is the correct way to do Business Validation on entities?

Scheduled Pinned Locked Moved C#
asp-nettutorialquestioncsharpdatabase
10 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    Bastien Vandamme
    wrote on last edited by
    #1

    Hi, What is the correct way to do Business Validation on entities with Entity Framework 6. By business Validation I mean validation that require more than one entity in process with, sometime, a little more complex rules that involve all these entities. A validation that require the system to call he database. I already checked this post: [ScottGu's Blog - Class-Level Model Validation with EF Code First and ASP.NET MVC 3](https://weblogs.asp.net/scottgu/class-level-model-validation-with-ef-code-first-and-asp-net-mvc-3) But, like most example about EF and validation all validations are limited to simple check that consider only the current entity. I need to do some check based on other entities. Example: I have a order entity that contain a quantity of product but this quantity must be a multiple of a variable stored in my item entity. This is what I call the business validation. To perform this validation on order I need to go in database and check the item selected for this order.

    public class Order : IValidateObject
    {
        public int Id { get; set; }
        public int ItemId { get; set; }
        public int Quantity { get; set; }
        
        public IEnumerable Validate(ValidationContext validationContext)
        {
            var item = DbContext.Items.Find(ItemId); // <-- What about this?
            if (Quantity % item.Multiple != 0)
                yield return new ValidationResult("Quantity not multiple of item", new\[\] {Quantity});
        }
    }
    
    public class Item
    {
        public int Id { get; set; }
        public int Multiple { get; set; }
    }
    

    How should I implement this kind of business validation that require other entities? I'm more looking for a good tutorial about this subject. I search but each time I think I find the subject the tutorial is limited to classic validation with Data Annotation or other type of classic validation. Maybe you will juste tell me there is no problem to class my context in the Validate method. It is just that most of tutorial separate the entity layer from the context layer suggesting entities must only be simple POCO with no behavior. I most and most disagree with this but I feel alone.

    L Richard DeemingR 2 Replies Last reply
    0
    • B Bastien Vandamme

      Hi, What is the correct way to do Business Validation on entities with Entity Framework 6. By business Validation I mean validation that require more than one entity in process with, sometime, a little more complex rules that involve all these entities. A validation that require the system to call he database. I already checked this post: [ScottGu's Blog - Class-Level Model Validation with EF Code First and ASP.NET MVC 3](https://weblogs.asp.net/scottgu/class-level-model-validation-with-ef-code-first-and-asp-net-mvc-3) But, like most example about EF and validation all validations are limited to simple check that consider only the current entity. I need to do some check based on other entities. Example: I have a order entity that contain a quantity of product but this quantity must be a multiple of a variable stored in my item entity. This is what I call the business validation. To perform this validation on order I need to go in database and check the item selected for this order.

      public class Order : IValidateObject
      {
          public int Id { get; set; }
          public int ItemId { get; set; }
          public int Quantity { get; set; }
          
          public IEnumerable Validate(ValidationContext validationContext)
          {
              var item = DbContext.Items.Find(ItemId); // <-- What about this?
              if (Quantity % item.Multiple != 0)
                  yield return new ValidationResult("Quantity not multiple of item", new\[\] {Quantity});
          }
      }
      
      public class Item
      {
          public int Id { get; set; }
          public int Multiple { get; set; }
      }
      

      How should I implement this kind of business validation that require other entities? I'm more looking for a good tutorial about this subject. I search but each time I think I find the subject the tutorial is limited to classic validation with Data Annotation or other type of classic validation. Maybe you will juste tell me there is no problem to class my context in the Validate method. It is just that most of tutorial separate the entity layer from the context layer suggesting entities must only be simple POCO with no behavior. I most and most disagree with this but I feel alone.

      L Offline
      L Offline
      Lost User
      wrote on last edited by
      #2

      The "Enumerable" makes no sense. "Validation" is an all or nothing proposition. If you want to return multiple error / messages, return a list. If the list is "empty", you might consider things valid and then do a "save". Other than that, you've provide no information about the environment: online, batch, whatever.

      It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it. ― Confucian Analects: Rules of Confucius about his food

      Richard DeemingR 1 Reply Last reply
      0
      • L Lost User

        The "Enumerable" makes no sense. "Validation" is an all or nothing proposition. If you want to return multiple error / messages, return a list. If the list is "empty", you might consider things valid and then do a "save". Other than that, you've provide no information about the environment: online, batch, whatever.

        It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it. ― Confucian Analects: Rules of Confucius about his food

        Richard DeemingR Offline
        Richard DeemingR Offline
        Richard Deeming
        wrote on last edited by
        #3

        The IEnumerable<ValidationResult> is just how the IValidatableObject interface works: IValidatableObject.Validate(ValidationContext) Method (System.ComponentModel.DataAnnotations) | Microsoft Docs[^] It works that way because each validation error can be associated with one or more properties of the object being validated, and some UI frameworks will use that to display the error next to the relevant control.


        "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

        "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

        L 1 Reply Last reply
        0
        • B Bastien Vandamme

          Hi, What is the correct way to do Business Validation on entities with Entity Framework 6. By business Validation I mean validation that require more than one entity in process with, sometime, a little more complex rules that involve all these entities. A validation that require the system to call he database. I already checked this post: [ScottGu's Blog - Class-Level Model Validation with EF Code First and ASP.NET MVC 3](https://weblogs.asp.net/scottgu/class-level-model-validation-with-ef-code-first-and-asp-net-mvc-3) But, like most example about EF and validation all validations are limited to simple check that consider only the current entity. I need to do some check based on other entities. Example: I have a order entity that contain a quantity of product but this quantity must be a multiple of a variable stored in my item entity. This is what I call the business validation. To perform this validation on order I need to go in database and check the item selected for this order.

          public class Order : IValidateObject
          {
              public int Id { get; set; }
              public int ItemId { get; set; }
              public int Quantity { get; set; }
              
              public IEnumerable Validate(ValidationContext validationContext)
              {
                  var item = DbContext.Items.Find(ItemId); // <-- What about this?
                  if (Quantity % item.Multiple != 0)
                      yield return new ValidationResult("Quantity not multiple of item", new\[\] {Quantity});
              }
          }
          
          public class Item
          {
              public int Id { get; set; }
              public int Multiple { get; set; }
          }
          

          How should I implement this kind of business validation that require other entities? I'm more looking for a good tutorial about this subject. I search but each time I think I find the subject the tutorial is limited to classic validation with Data Annotation or other type of classic validation. Maybe you will juste tell me there is no problem to class my context in the Validate method. It is just that most of tutorial separate the entity layer from the context layer suggesting entities must only be simple POCO with no behavior. I most and most disagree with this but I feel alone.

          Richard DeemingR Offline
          Richard DeemingR Offline
          Richard Deeming
          wrote on last edited by
          #4

          In this case, you could probably implement the validation by adding a navigation property:

          public class Order : IValidateObject
          {
          public int Id { get; set; }
          public int ItemId { get; set; }
          public int Quantity { get; set; }

          public virtual Item Item { get; set; }
          
          public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
          {
              if (Quantity % Item.Multiple != 0)
              {
                  yield return new ValidationResult("Quantity not multiple of item", new\[\] { Quantity });
              }
          }
          

          }

          However, you'd need to test to make sure the property was always set. Alternatively, you could override the ValidateEntity method on your DbContext: DbContext.ValidateEntity(DbEntityEntry, IDictionary<Object,Object>) Method (System.Data.Entity) | Microsoft Docs[^] NB: This wouldn't work with EF Core - it no longer tries to validate the entities before saving them. If you wanted to validate the entities before trying to save them, you would have to write your own validation logic - for example: Improving Model Validation for Entity Framework Core 2.0 | Ballard Software[^]


          "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

          "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

          1 Reply Last reply
          0
          • Richard DeemingR Richard Deeming

            The IEnumerable<ValidationResult> is just how the IValidatableObject interface works: IValidatableObject.Validate(ValidationContext) Method (System.ComponentModel.DataAnnotations) | Microsoft Docs[^] It works that way because each validation error can be associated with one or more properties of the object being validated, and some UI frameworks will use that to display the error next to the relevant control.


            "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

            L Offline
            L Offline
            Lost User
            wrote on last edited by
            #5

            So, instead of "one" call, he does multiple calls to get all the errors "because there may be multiple properties". Sorry, I fail to see the connection. The interface is at the "class level", not the property level.

            It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it. ― Confucian Analects: Rules of Confucius about his food

            Richard DeemingR 1 Reply Last reply
            0
            • L Lost User

              So, instead of "one" call, he does multiple calls to get all the errors "because there may be multiple properties". Sorry, I fail to see the connection. The interface is at the "class level", not the property level.

              It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it. ― Confucian Analects: Rules of Confucius about his food

              Richard DeemingR Offline
              Richard DeemingR Offline
              Richard Deeming
              wrote on last edited by
              #6

              No, there's one call to get the list of validation errors. Each error can be associated with one or more properties, by specifying the member names in the ValidationResult. The interface is designed for validation rules on a class which need access to other properties of the class. Validation attributes on a property only get access to that property's value. That's fine for simple validation rules like "required" or "greater than zero", but it doesn't work for things like "confirm password must be equal to password".


              "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

              "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

              L 1 Reply Last reply
              0
              • Richard DeemingR Richard Deeming

                No, there's one call to get the list of validation errors. Each error can be associated with one or more properties, by specifying the member names in the ValidationResult. The interface is designed for validation rules on a class which need access to other properties of the class. Validation attributes on a property only get access to that property's value. That's fine for simple validation rules like "required" or "greater than zero", but it doesn't work for things like "confirm password must be equal to password".


                "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

                L Offline
                L Offline
                Lost User
                wrote on last edited by
                #7

                Still doesn't answer why an enumerable is "better" than a list in this case. All you're doing is trading a yield for an Add (and making it more complicated for some … as indicated by OP's post).

                It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it. ― Confucian Analects: Rules of Confucius about his food

                Richard DeemingR P 2 Replies Last reply
                0
                • L Lost User

                  Still doesn't answer why an enumerable is "better" than a list in this case. All you're doing is trading a yield for an Add (and making it more complicated for some … as indicated by OP's post).

                  It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it. ― Confucian Analects: Rules of Confucius about his food

                  Richard DeemingR Offline
                  Richard DeemingR Offline
                  Richard Deeming
                  wrote on last edited by
                  #8

                  The interface defines the method as returning IEnumerable<ValidationResult>. If you wanted to return a List<ValidationResult> instead of using an iterator method, you could certainly do that. But I don't see how it would make things significantly simpler.


                  "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

                  "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

                  1 Reply Last reply
                  0
                  • L Lost User

                    Still doesn't answer why an enumerable is "better" than a list in this case. All you're doing is trading a yield for an Add (and making it more complicated for some … as indicated by OP's post).

                    It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it. ― Confucian Analects: Rules of Confucius about his food

                    P Offline
                    P Offline
                    phil o
                    wrote on last edited by
                    #9

                    Gerry Schmitz wrote:

                    Still doesn't answer why an enumerable is "better" than a list in this case.

                    No one ever said it is "better". This is just how the interface is built. Implementers are free to return whatever they want, provided it implements IEnumerable.

                    "Five fruits and vegetables a day? What a joke! Personally, after the third watermelon, I'm full."

                    L 1 Reply Last reply
                    0
                    • P phil o

                      Gerry Schmitz wrote:

                      Still doesn't answer why an enumerable is "better" than a list in this case.

                      No one ever said it is "better". This is just how the interface is built. Implementers are free to return whatever they want, provided it implements IEnumerable.

                      "Five fruits and vegetables a day? What a joke! Personally, after the third watermelon, I'm full."

                      L Offline
                      L Offline
                      Lost User
                      wrote on last edited by
                      #10

                      Finally. Thanks for that.

                      It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it. ― Confucian Analects: Rules of Confucius about his food

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups