Nik's Technology Blog

Travels through programming, networks, and computers

No defining declaration found for implementing OnValidate(System.Data.Linq.ChangeAction)

If you happen to be getting an error message like the one below, then read on.

Error    1    No defining declaration found for implementing declaration of partial method 'mvcCMS.Models.WebPage.OnValidate(System.Data.Linq.ChangeAction)'    C:\mvcCMS\Models\WebPage.cs    28    22    mvcCMS


I'm using LINQ to SQL designer in Visual Studio to create a database schema and I'm using a partial class to extend the code generated by the designer.

In the example below I am using the pattern used by NerdDinner.com to add business rules/validation to the model classes LINQ to SQL built based on my database schema.

namespace mvcCMS.Models
{
    public partial class WebPage
    {
        public bool IsValid
        {
            get { return (GetRuleViolations().Count() == 0); }
        }
        public IEnumerable<RuleViolation> GetRuleViolations()
        {
            if (String.IsNullOrEmpty(Title))
                yield return new RuleViolation("Title is required", "Title");
            if (String.IsNullOrEmpty(Text))
                yield return new RuleViolation("Web copy is required", "Text");

            yield break;
        }
        partial void OnValidate(ChangeAction action)
        {
            if (!IsValid)
                throw new ApplicationException("Rule violations prevent saving");
        }
    }
}

Where OnValidate() is a partial method LINQ to SQL provides which enables us to be notified when the object is about to be persisted to the database, so we can check all our business rules have been met before the object is flushed to the database.

An empty OnValidate() method is part of the designer generated code for your data class located in the #region Extensibility Method Definitions and it seems that these Extensibility Method Definitions only get added to the designer code when your tables have primary keys.

When a table is dragged onto the Object Relational Designer in Visual Studio the classes that are generated will only implement INotifyPropertyChanging and INotifyPropertyChanged if your tables have primary keys.  If the classes don't implement these interfaces the code won't implement the OnValidate() method, and if the OnValidate() method doesn't exist your partial class won't compile.

The Solution

The solution is simple.  Add a primary key to your database table, delete the associated data class from the Object Relational Designer and then drag the database table from Server Explorer back onto the Object Relational Designer surface.

You should then find the designer generated code now implements INotifyPropertyChanging and INotifyPropertyChanged and the class contains a definition for OnValidate() in the #region Extensibility Method Definitions.  Your code should now compile.