views:

244

answers:

3

I am working on a Data Access Layer Design, we have not finalized what ORM we are going to use as of yet. I am leaning towards NHibernate + FluentMappings + Nhibernate.Linq but depending on project timelines we could even wait for EF4. I want to replace methods like :

IList<Customer> FindById(int id);

IList<Customer> FindByName(string fullName);

to

IList<Customer> FindByCriteria(Func<Customer, bool> criteria);

or even

IList<T> FindByCriteria(Func<T, bool> criteria)

so the idea is to chain or build a criteria based on the requirement (from UI or Business ) dynamically to a repository or DAO object. Any code samples, links , blog posts , hints are welcome.

Thanks in advance!

+1  A: 

Link to the first post of a series below. Not 100% on point, but the general concept applies. The ORM used in the article is LLBLGen Pro, but should be applicable to any mature ORM framework:

Dynamic Search Objects Part 1–Introduction

Phil Sandler
Thanks Phil ! I will look into it.
Perpetualcoder
+1  A: 

If you want to work only with lambdas you will have to deal with the System.LINQ.Expression class. It allows you to access the code the lambda represents.

The types around IQueryable may also be interesting for you.

winSharp93
+1  A: 

If you are writing an ORM, then you should be asking this question.

If you are writing an application built on top of an ORM, it should already have the capability to express generic queries (such as LINQ expressions). Your task for your application is to harness that generic query capability into system-specific queries like "find customer by name".

Generic queries are a level of abstraction directly below application-specific queries. Repositories should not themselves contain generic capabilities.

See my answer here for more info and a code sample:

http://stackoverflow.com/questions/1230571/advantage-of-creating-a-generic-repository-vs-specific-repository-for-each-objec

Bryan Watts
not sure I understand what you mean. I understand the link, my question is more around how to build the expression trees or predicates dynamically for any BO or Entity.
Perpetualcoder
Your question is about how to replace specific queries with generic ones, i.e. remove Find(id) and Find(name) and replace with Find(criteria), at the application level. My answer is that is an anti-pattern. The data framework (ORM) enables generic queries; your application should enable specific queries. Enabling generic queries at the application level doesn't buy you anything; you want to *encapsulate* how to find a customer by name, not leave it up to the client to know.
Bryan Watts
Perpetualcoder
Ok, I see how what you are asking and what I said relate. You are describing exactly how LINQ works. The `System.Linq.Expressions` namespace contains objects which can describe code, which is exactly what you need. See my answer here: http://stackoverflow.com/questions/497121/building-dynamic-linq-queries-based-on-combobox-value. I was just making sure that you did not put the predicate building responsibility on the business layer client.
Bryan Watts