views:

48

answers:

1

Consider the following code, which is calling against an EF generated data context:

var context = new DataContext();
var employees = context.Employees.Include("Department");

If I change the name of the Department relationship then this code is going to start throwing a runtime error. So is there any way to call the .Include() method in a safe manner, so I get compile time checking for all the relationships being referenced?

+3  A: 

I did a little extension to ObjectQuery which goes like this

public static ObjectQuery<TEntity> Include<TEntity, TProperty>(this ObjectQuery<TEntity> query, Expression<Func<TEntity, TProperty>> expression) where TEntity : class
{
    string name = expression.GetPropertyName();
    return query.Include(name);
}

which also requires

public static class ExpressionExtensions
{
    public static string GetPropertyName<TObject, TProperty>(this Expression<Func<TObject, TProperty>> expression) where TObject : class
    {
        if (expression.Body.NodeType == ExpressionType.Call)
        {
            MethodCallExpression methodCallExpression = (MethodCallExpression)expression.Body;
            string name = ExpressionExtensions.GetPropertyName(methodCallExpression);
            return name.Substring(expression.Parameters[0].Name.Length + 1);
        }
        return expression.Body.ToString().Substring(expression.Parameters[0].Name.Length + 1);
    }

    private static string GetPropertyName(MethodCallExpression expression)
    {
        MethodCallExpression methodCallExpression = expression.Object as MethodCallExpression;
        if (methodCallExpression != null)
        {
            return GetPropertyName(methodCallExpression);
        }
        return expression.Object.ToString();
    }
}

with that you can do

var context = new DataContext();      
var employees = context.Employees.Include(e => e.Department);

which is going to be check at compile time. If i remember correctly, this methods doesn't work for many-to-many relationship but it works for stuff like

var item = context.Employees.Include(e => e.Department.Manager);

Good luck to you

moi_meme
I like this solution, even though I don't understand it. Any idea why it doesn't work with many-to-many? Could it be changed to cope with this too? Then we will have the ultimate solution.
Mikey Cee
All it is doing is taking the name of the property and putting it to string so your Entity must have the same name as that property for his to work, so it might work for many-to-many
moi_meme