Monthly Archives: February 2009

OnValidate-like validation in Entity Framework

Yesterday, while doing Entity Framework training, I got a good question. LINQ to SQL has a nice event called OnValidate, where you can validate your data. But Entity Framework classes don’t. As the only one good point to do the validation of entities in Entity Framework is during in SaveChanges in SavingChanges event, we have to utilize this event and build validation there.

And as we have access to our ObjectContext, we can get information from ObjectStateManager about, for us, interesting entities and do some validation. Good practice is to put your validation inside the object. To simplify the work with these objects, we can implement in partial classes some interface with i.e. IsValid property. Then before sending data to the database we can easily perform the validation.

First create some interface:

interface IValidatable
{
    bool IsValid { get; }
}

And implement it in entity objects:

partial class Master : IValidatable
{
    public bool IsValid
    {
        get
        {
            return (!string.IsNullOrEmpty(this.Foo) && !string.IsNullOrEmpty(this.Bar));
        }
    }
}

partial class Detail : IValidatable
{
    public bool IsValid
    {
        get
        {
            return (this.Bar.Length > 3);
        }
    }
}

And finally we can implement SavingChanges event (maybe the OnContextCreated can be used to wire up this event):

MyEntities entities = (MyEntities)sender;

foreach (var item in
    entities.ObjectStateManager.GetObjectStateEntries(System.Data.EntityState.Modified | System.Data.EntityState.Added)
        .Where(entry => (entry.Entity is IValidatable) && (!entry.IsRelationship))
        .Select(entry => entry.Entity as IValidatable))
{
    if (!item.IsValid)
    {
        // throw some exception
    }
}

Coalesce operator in Entity Framework

You may wonder how to use usefull coalesce operator in Entity Framework. If you look to some EF provider, i.e. for Firebird ;) you will see, that there’s no coalesce related code. So you will end up, probably, with code like x => (x.BAR != null ? x.BAR : "N/A"). And that’s fun until you need longer chain of (not) null checks. But as Diego Vega pointed in some forum thread, you can use ?? operator. And the x => x.BAR ?? x.BAR ?? x.BAR ?? "N/A" looks, in my opinion, better.

But you have to be carefull, because in EF internally it’s handled same as first case, so using CASE. That means you may hit some query length limits of you database very easily. On the other hand, using it for normal stuff, you probably don’t need to care how it’s translated inside – important is, that the query is correct.

"Local" Queries 2nd edition

Danny Simmons posted small helper method for runnning queries against local cache (in ObjectContext). Many of you are probably using similar method. But I don’t like to have to specify entity set as a string. That’s a first step for refactoring problems. :)

Thus I created little bit different version, using same trick as Matthieu Mezil with Include.

public static IEnumerable<TEntity> Local<TEntity, TObjectContext>(this ObjectContext context, Expression<Func<TObjectContext, ObjectQuery<TEntity>>> entitySet) where TEntity : class
{
    if (!(entitySet.Body is MemberExpression))
        throw new ArgumentException("entitySet");

    string name = ((MemberExpression)entitySet.Body).Member.Name;
    return context.Local<TEntity>(name);
}

It’s using Danny’s original one to do the dirty work ;) , so it’s just a small helper for helper. You can call it like e.Local<DETAIL, MyEntities>(x => x.Details).ToArray(); instead of e.Local<DETAIL>("Details").ToArray();.