views:

210

answers:

1

I am working on a repository pattern where the API look as follows:

var visitor = repository.Find(x => x.EmailAddress == credentials.EmailAddress &&
                              x.Password == credentials.Password);

where visitor is a domain object and x represents this domain object. The method signature of the Find method on the repository is:

T Find(Func<T, bool> query);

This is all wonderful until I attempt to use this with Linq2Sql because linq2sql creates its own objects and as a result when I want to call:

context.visitors.FirstOrDefault(query);

there is a type mismatch because linq2sql expects a function of the type it created and not the function I am passing in.

A: 

Well to start with you'll need to change your Find signature to:

T Find(Expression<Func<T, bool>> query);

LINQ to SQL needs to have the logic as an expression tree instead of a plain delegate, otherwise it can't work out how to translate it into SQL.

Beyond that, I'm afraid it's not terribly clear - it sounds like you're not using the same domain classes for your repository and LINQ to SQL. Is that right? That sounds like a potential problem; at the very least it's going to make life pretty tricky.

Jon Skeet
Yes... I do not want to use the Linq2SQL classes as my domain objects because I may want to add behavior to my domain objects and I may also want to restrict the accessability of the members.
Michael Mann
Adding behaviour is easy: the generated classes are *partial classes* which means you can add your own behaviour in a separate file, but still in the same class. You can specify property accessibility in the dbml file.
Jon Skeet
That certianly seems like a much simpler approach than transforming expression trees from one type into another. I will go with that approach and restrict visibility and access through interfaces.
Michael Mann