Monthly Archives: April 2009

Load with filtering or limiting

Today, you have two direct options how to load related data for given entity. Use Include or use Load method. In this post, I’ll focus on Load, because this problem on Include is little bit easier than on Load. Unfortunately the Load method isn’t providing any option to filter or limit what you’re loading. That means, if you have customer with for example 200 invoices, you’ll load all these 200 invoice, even if you need only first 5 or something like that. And that’s wasting of resources.

But the solution isn’t so hard. First, Entity Framewok has automagic wiring of related entities. Hence if you load one customer and then some invoices. If there will be invoices for this customer the navigation properties will be working without problem and without any work form you. So the first solution for filtered load is simply load detail record with your where condition and condition on the master entity. But that’s “a lot” of work ;) and developers are lazy. Fortunately there’s another way.

The EntityReference has a method CreateSourceQuery returning ObjectQuery. With this and knowledge from previous paragraph you can easily create overload/extension method for Load to load only what you need.

public static void Load<T>(this EntityCollection<T> relatedEnd, Expression<Func<T, bool>> predicate, MergeOption mergeOption) where T : class, IEntityWithRelationships
{
	(relatedEnd.CreateSourceQuery().Where(predicate) as ObjectQuery<T>).Execute(mergeOption).ToArray();
}

public static void Load<T>(this EntityReference<T> relatedEnd, Expression<Func<T, bool>> predicate, MergeOption mergeOption) where T : class, IEntityWithRelationships
{
	(relatedEnd.CreateSourceQuery().Where(predicate) as ObjectQuery<T>).Execute(mergeOption).ToArray();
}

public static void Load<T>(this EntityCollection<T> relatedEnd, Expression<Func<T, bool>> predicate) where T : class, IEntityWithRelationships
{
	Load(relatedEnd, predicate, MergeOption.AppendOnly);
}

public static void Load<T>(this EntityReference<T> relatedEnd, Expression<Func<T, bool>> predicate) where T : class, IEntityWithRelationships
{
	Load(relatedEnd, predicate, MergeOption.AppendOnly);
}

Above is simple extension method, to help you load only related entities you need based on some where condition. You can take the same idea and create a version with First, for instance. Or any filter or limit you may need.

BuildNotContainsExpression

Colin Meek wrote extremely handy method for using it as Contains method we know it’s on collections, but not supported in Entity Framework right now (v1/EF3.5). The method is called BuildContainsExpression. Today in MSDN forums I needed this, but negated. Thus I wrote the BuildNotContainsExpression. It’s just small change of original Colin’s method.

static Expression<Func<TElement, bool>> BuildNotContainsExpression<TElement, TValue>(Expression<Func<TElement, TValue>> valueSelector, IEnumerable<TValue> values)
{
    if (null == valueSelector) { throw new ArgumentNullException("valueSelector"); }
    if (null == values) { throw new ArgumentNullException("values"); }

    ParameterExpression p = valueSelector.Parameters.Single();

    // p => valueSelector(p) != values[0] && valueSelector(p) != ...

    if (!values.Any())
    {
        return e => true;
    }

    var equals = values.Select(value => (Expression)Expression.NotEqual(valueSelector.Body, Expression.Constant(value, typeof(TValue))));
    var body = equals.Aggregate<Expression>((accumulate, equal) => Expression.And(accumulate, equal));
    return Expression.Lambda<Func<TElement, bool>>(body, p);
}

Instead of triggers in MS SQL and Entity Framework problem

I don’t like the model of instead of and after triggers in MS SQL. The before and after ones are, in my opinion, better. Anyway I needed to do some complex tests, not possible with check constraints, before inserting. Hence I jumped into instead of trigger. No problem in a view. Or not?

The Entity Framework is smart enough to get all server generated columns back when inserting (or updating) – see StoreGeneratedPattern. But the problem is how the identity column, often used for primary keys, is retrieved. The command issued after insert looks like (particular shape depends on other store generated columns and concurrency checks): select <PK column> from <some table> where @@ROWCOUNT > 0 and <PK column> = scope_identity().The problem is, that if you generate new PK value in trigger, it is different scope. Thus this command returns zero rows and EF will throw exception.

Hmm, this isn’t the way. :( So one of the solutions is move away from instead of triggers and use stored procedures (remember that you need all three) and result binding (you might be forced to create SPs (of fake ones in SSDL) for some related objects too). It’s not easiest solution, but works nice and you don’t have to introduce hacks etc.

Entity Framework and Firebird Embedded

Did you ever think about how cool would it be to have fully featured SQL database, without installation (just xcopy) and with Entity Framework support?

I was wondering whether the Entity Framework support I’m creating in FirebirdClient will work with Embedded version. Taking into account that the communication layers are under the EF support, there should be no problem. But you’ll never be sure until you try it. ;) And it works!

So what you need to do? Well almost nothing. Just change connection string and it works. But maybe you’re starting with fresh app, thus I’ll give you some advices. To be able to generate proper model (at least the SSDL), you need 2.5 Beta 1 (released couple days ago) – it has the left outer join bug fixed. Also since 2.5 you’ll be able to connect to database using different applications, therefore debugging the application and using i.e. isql together is even easier. On the development machine you probably already have .NET Framework 3.5 with SP1, but also remember to have it on target machine. (Saying that you need FirebirdClient is I think worthless. ;) )

And that’s pretty much it. After you finish your app you can deploy it with i.e. 2.1 Embedded (it’s the current stable), the app will run just fine.

Isn’t it nice? Full power of proper database server and full power of Entity Framework all in one.

(Not) interesting observation on LINQ

I’ve found interesting stuff in last couple of … I don’t know. Well it’s not interesting because everybody knows it :) , but using it this way, was for me like going the other direction.

First is that code comprehension (which I don’t like, btw) is translated into well known methods like Select, Where etc. You are using this in LINQ often. But it’s not coupled to IQueryable or whatever, it’s just dumb translation during compile. Hence you can easily provide i.e. only Select and Where methods in your class and use it with code comprehension. Not worrying about IQueryable or runtime exceptions if don’t support some methods. Obvious, right? I told you. :)

Another observation is that your i.e. Where method may return completely different class or collection of classes. This is probably not usefull at all, although as a mind blowing code to torture your colleagues it can be fun. ;)

Sorting in IQueryable using string as column name

Today my UI/ASP.NET guru workmate asked me whether it’s possible to provide sorting methods on queries (in our case Entity Framework) using column name as string instead of expression. Well, I thought, why it shouldn’t.

My first attention got to the MetadataWorkspace. After couple of attempts it became clear that this is not the best way. So I switched my attention to the expression trees. And that was the way. I ended up with this result.

private static IOrderedQueryable<T> OrderingHelper<T>(IQueryable<T> source, string propertyName, bool descending, bool anotherLevel)
{
    ParameterExpression param = Expression.Parameter(typeof(T), string.Empty); // I don't care about some naming
    MemberExpression property = Expression.PropertyOrField(param, propertyName);
    LambdaExpression sort = Expression.Lambda(property, param);

    MethodCallExpression call = Expression.Call(
        typeof(Queryable),
        (!anotherLevel ? "OrderBy" : "ThenBy") + (descending ? "Descending" : string.Empty),
        new[] { typeof(T), property.Type },
        source.Expression,
        Expression.Quote(sort));

    return (IOrderedQueryable<T>)source.Provider.CreateQuery<T>(call);
}

public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source, string propertyName)
{
    return OrderingHelper(source, propertyName, false, false);
}

public static IOrderedQueryable<T> OrderByDescending<T>(this IQueryable<T> source, string propertyName)
{
    return OrderingHelper(source, propertyName, true, false);
}

public static IOrderedQueryable<T> ThenBy<T>(this IOrderedQueryable<T> source, string propertyName)
{
    return OrderingHelper(source, propertyName, false, true);
}

public static IOrderedQueryable<T> ThenByDescending<T>(this IOrderedQueryable<T> source, string propertyName)
{
    return OrderingHelper(source, propertyName, true, true);
}

It’s a set of extension methods with similar signature as the classic ones OrderBy, ThenBy, etc. only taking string parameter instead of expression. This string parameter is name of field in class to be used for sorting. Enjoy.