none
Code First POCO Validation Question RRS feed

  • Question

  • I'm still confused about what validation method(s) to use with my POCO classes (in a DDD approach).

    1 - I can use Data Annotations on individual properties

    2 - I can implement the IValidatableObject interface on my POCO classes -> can this also be used with an individual property?

    3 - Refering to e.g. Julia Lerman book on Entity Framework I can use in every POCO class a Validate() method and in the context classes ValidateBeforeSave() methods that calls the Validate() methods.

    Is the best practice to use the combination of methods 1 and 2 or is it method 3?

    Thanks.

     

     

    Wednesday, June 29, 2011 1:08 PM

Answers

  • With EF 4.1 your best choice is to use data annotations. IValidatableObject interface lives in System.ComponentModel.DataAnnotations namespace and therefore is part of this approach. You use IValidatableObject interface in cases where simple attributes are not enough - for instance there are two properties properties that depend on each other. Referring to your original post:

     I can implement the IValidatableObject interface on my POCO classes -> can this also be used with an individual property?

    If you decide to implement IValidatableObject interface you write the validation logic and therefore you decide what to validate.

    I don't think you will be able to follow the "ValidateBeforeSave" way with EF 4.1. My understanding is that this solution is meant for Entity Framework 4.0. EF 4.1/CodeFirst is built on top of Entity Framework 4.0. You can think of it as of a wrapper that just simplifies the API. As a result something meant for Entity Framework 4.0 most likely will not work wih Entity Framework 4.1 as it usually requires to override and/or customize the behavior of ObjectContext.

    To answer your question - to validate entities with EF 4.1 you use the following:

    1) use built-in validation attributes from System.ComponentModel.DataAnnotations namespace

    2) if you need more complex validation e.g. the value of a property is not sufficient to determine whether it is valid or not use IValidatableObject or CustomValidationAttribute

    3) if for some reason you cannot use either 1 or 2 (e.g. you cannot modify entities since these are in an assembly you don't own) you can override ValidateEntity method in DbContext class to add your own validation logic.

    Here is a link to a blog post I wrote about validation in EF 4.1:

    http://blogs.msdn.com/b/adonet/archive/2010/12/15/ef-feature-ctp5-validation.aspx

    and one more that described what changed in the final release:

    http://blogs.msdn.com/b/adonet/archive/2011/05/27/ef-4-1-validation.aspx

    Pawel

    • Marked as answer by Guy Dillen Tuesday, July 19, 2011 7:21 PM
    Tuesday, July 19, 2011 7:04 PM
  • Guy, I've just come across this thread. When I wrote the book, we didn't have the validaton API in the Entity Framework so I wasn't leveraging the Data Annotations or IValidatableObject.

    Now I am using the ValidationAPI and Pawel's is in line with my current approach which also let's me use the validationAttributes and IValidatableObject outside of the EF Valoidation API if I want. Now that I have learned so much more about IValidatableObject, I would have used that to enable calling Reservation.Validate instead of rolling my own ..even without the Validation API.

    I'm just now writing a chapter on the Validation API for the next short book...Programming Entity Framework :DbContext.

    Thanks Pawel! :)


    Julie Lerman, Author of Programming Entity Framework, MVP
    • Marked as answer by Guy Dillen Thursday, December 29, 2011 11:01 AM
    Saturday, October 29, 2011 7:34 PM

All replies

  • Hi GuyD,

    Welcome!

    You can refer this post: http://social.msdn.microsoft.com/Forums/en/adonetefx/thread/1748587a-f13c-4dd7-9fec-c8d57014632c

    It seems it's not supported in POCO now.

    Have a nice day.


    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.



    Thursday, June 30, 2011 11:06 AM
    Moderator
  • Thanks.

    Actually where I'm confused is the following:

     

    In Julie Lerman's book validation is performed as follows:

    Example 24-23. The Reservation class’s Validate method

    public bool Validate(out string validationError)

    {

    bool isvalid = true;

    validationError = "";

    if (TripID == null & Trip==null)

    {

    isvalid = false;

    validationError = "Trip";

    }

    if (ContactID == 0 & Customer == null)

    {

    isvalid = false;

    validationError += ",Contact";

    }

    if (ReservationDate == DateTime.MinValue)

    {

    isvalid = false;

    validationError += ",Date";

    }

    if (validationError != "")

    validationError = string.Format

    ("[ReservationID {0}: {1}]", ReservationID, validationError);

    return isvalid;

    }

     

    Example 24-24. Validation in the context classes

    public bool ValidateBeforeSave(out string validationErrors)

    {

    bool isvalid = true;

    validationErrors = "";

    foreach (var res in ManagedEntities<Reservation>())

    {

    string validationError;

    bool isResValid = res.Validate(out validationError);

    if (!isResValid)

    {

    isvalid = false;

    validationErrors += validationError;

    }

    }

    return isvalid;

    }

     

    So in fact in the POCO classes having Validate methods and in context (or I suppose when implementing the Repository pattern) adding ValidateBeforeSave methods.

     

    At the same time I mentioned in the webcasts of Julie on msdn on EF 4.1 Code First she uses  Data Annotations, implementing IValidatableObject interface.

     

    So, if i'm right two different approaches for Validation of POCO classes?!

     

    What is the recommended method? (Dis)advantages of the both approaches?

     

    Thanks.

     

    Guy Dillen

     

    Thursday, June 30, 2011 6:44 PM
  • Hi Guy,

    Here is a blog about Validation of EF4.1: http://blogs.msdn.com/b/adonet/archive/2011/05/27/ef-4-1-validation.aspx

    I hope it helps.

    Have a nice day.


    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, July 5, 2011 6:57 AM
    Moderator
  • I'm still confused what is the recommended way for Validation using POCO's and EF 4.1 code first. As I mentioned in my previous post Julie Lerman in her book on Entity Framework does validation as in the code snippet; at the same time in her learning video's http://msdn.microsoft.com/en-us/data/gg193959 and http://msdn.microsoft.com/en-us/data/gg193958 she uses Data Annotations / Code First Fluent API Validations / IValidatableObject with POCOs for More Complex Validations.

    What is the recommended way?

    Thanks.

    Guy

     

     



    Tuesday, July 19, 2011 10:05 AM
  • With EF 4.1 your best choice is to use data annotations. IValidatableObject interface lives in System.ComponentModel.DataAnnotations namespace and therefore is part of this approach. You use IValidatableObject interface in cases where simple attributes are not enough - for instance there are two properties properties that depend on each other. Referring to your original post:

     I can implement the IValidatableObject interface on my POCO classes -> can this also be used with an individual property?

    If you decide to implement IValidatableObject interface you write the validation logic and therefore you decide what to validate.

    I don't think you will be able to follow the "ValidateBeforeSave" way with EF 4.1. My understanding is that this solution is meant for Entity Framework 4.0. EF 4.1/CodeFirst is built on top of Entity Framework 4.0. You can think of it as of a wrapper that just simplifies the API. As a result something meant for Entity Framework 4.0 most likely will not work wih Entity Framework 4.1 as it usually requires to override and/or customize the behavior of ObjectContext.

    To answer your question - to validate entities with EF 4.1 you use the following:

    1) use built-in validation attributes from System.ComponentModel.DataAnnotations namespace

    2) if you need more complex validation e.g. the value of a property is not sufficient to determine whether it is valid or not use IValidatableObject or CustomValidationAttribute

    3) if for some reason you cannot use either 1 or 2 (e.g. you cannot modify entities since these are in an assembly you don't own) you can override ValidateEntity method in DbContext class to add your own validation logic.

    Here is a link to a blog post I wrote about validation in EF 4.1:

    http://blogs.msdn.com/b/adonet/archive/2010/12/15/ef-feature-ctp5-validation.aspx

    and one more that described what changed in the final release:

    http://blogs.msdn.com/b/adonet/archive/2011/05/27/ef-4-1-validation.aspx

    Pawel

    • Marked as answer by Guy Dillen Tuesday, July 19, 2011 7:21 PM
    Tuesday, July 19, 2011 7:04 PM
  • Many thanks. Now it's clear to me.
    Tuesday, July 19, 2011 7:21 PM
  • Guy, I've just come across this thread. When I wrote the book, we didn't have the validaton API in the Entity Framework so I wasn't leveraging the Data Annotations or IValidatableObject.

    Now I am using the ValidationAPI and Pawel's is in line with my current approach which also let's me use the validationAttributes and IValidatableObject outside of the EF Valoidation API if I want. Now that I have learned so much more about IValidatableObject, I would have used that to enable calling Reservation.Validate instead of rolling my own ..even without the Validation API.

    I'm just now writing a chapter on the Validation API for the next short book...Programming Entity Framework :DbContext.

    Thanks Pawel! :)


    Julie Lerman, Author of Programming Entity Framework, MVP
    • Marked as answer by Guy Dillen Thursday, December 29, 2011 11:01 AM
    Saturday, October 29, 2011 7:34 PM
  • Hi Julie, I just found this thread and although a little old I'm hoping you may answer me. I've been reading about how lazy loading has been disabled during validation, which obviously is troublesome for implementing validation with data annotations and IValidatableObject. Is there a decent way to go around this, apart from having to load from outside the model every single property that needs to be available for validation. This approach goes against good encapsulation practices, having to know, as I said, from outside, all the properties that may be involved in validation and knowing when validation may execute for an entity so as to load them with include or something. Is it possible for me to allow lazy loading during validation?

    Thanks a lot,

    Amanda

    Monday, December 17, 2012 10:55 AM
  • Hi Julie, I just found this thread and although a little old I'm hoping you may answer me. I've been reading about how lazy loading has been disabled during validation, which obviously is troublesome for implementing validation with data annotations and IValidatableObject. Is there a decent way to go around this, apart from having to load from outside the model every single property that needs to be available for validation. This approach goes against good encapsulation practices, having to know, as I said, from outside, all the properties that may be involved in validation and knowing when validation may execute for an entity so as to load them with include or something. Is it possible for me to allow lazy loading during validation?

    Thanks a lot,

    Amanda

    Monday, December 17, 2012 10:55 AM
  • There are several reasons why lazy loading is disabled when validating entities. The first and most important is performance - having lazy loading turned on during validation could mean not only bringing the whole database to the client but also doing it in a very ineffective way by sending a lot of queries to the database. After bringing new entities to the context should these be validated as well - if yes, again we would bring even more entities (again lazy loading) and would have to validate these. If not, references to the "original" entities would have to be stored somewhere to know if they should be validated or not. In both cases you are looking at using more memory and doing more work. Another reason for disabling lazy loading is single responsibility priniciple - validation is supposed to validate entities and not doing bunch of other things. At the moment it's very clear - enities tracked (and - by default - not marked as deleted) are validated and nothing else. If lazy loading was turned on it's hard to tell what will be validated and what will not. Finally, if the entity is in the database it must have been valid when being saved. Since you don't have it in the context there are no changes to this entity so does it need to be validated at all? I assume that scenario here is a bit more complicated and you want to cross check some data from an entity that has changed with an entity that is in the database. You don't need to have lazy loading for this. You can either load the entities before saving changes or you can try loading them manually when you need them (I have not tried it though so no guarantees).
    Monday, December 17, 2012 6:05 PM