Ayende @ Rahien

Hi!
My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:

ayende@ayende.com

+972 52-548-6969

, @ Q c

Posts: 5,972 | Comments: 44,509

filter by tags archive

Ask AyendeHandling filtering


With regards to my quests against repositories, Matt asks:

…if my aggregate root query should exclude entities that have, for example, and IsActive = false flag, I also don't want to repeatedly exclude the IsActive = false entities. Using the repository pattern I can expose my Get method where internally it ALWAYS does this.

The problem with this question is that it make a false assumption, then go ahead and follow on that false assumption. The false assumption here is that the only way to handle the IsActive = false in by directly querying that. But that is wrong.

With NHibernate, you can define that with a where condition, or as a filter. With RavenDB, you can define that inside a query listener. You can absolutely set those things up as part of your infrastructure, and you won’t need to create any abstractions for that.

More posts in "Ask Ayende" series:

  1. (28 Feb 2012) Aggregates and repositories
  2. (31 Jan 2012) What about the QA env?
  3. (25 Jan 2012) Handling filtering
  4. (19 Jan 2012) Life without repositories, are they worth living?
  5. (17 Jan 2012) Repository for abstracting multiple data sources?

Comments

Colin Scott

I've worked with systems that do that. It's a really great source of confusing NullReferenceExceptions when a record that is in the database doesn't get returned by an abstraction that doesn't in any way indicate that it does such filtering. It's also a hindrance when writing the code that has to deal with the inactive records as suddenly none of the common structure applies.

(The NullReferenceExceptions on records not being found is an entirely separate flaw)

Matt

I don't agree the assumption is flawed - your context is different.

The original comment was to do with a pattern of implementation, but the answer uses NHibernate to say that it's incorrect.

What if I'm not using NHibernate, and don't have filtering at my disposal, or anything like it?

Or even if I am using NHib, what if there are valid use cases for fetching everything with IsActive = false - the DEFAULT retrieval mechanism should filter these out but in some cases I want to see them? I don't want a global query override that prevents my data layer from returning the records.

Leaving it up to the developers to always exclude the relevant records is not a great idea on a large system, so I absolutely agree that having it as part of your infrastructure is 1st prize, but I'm not sold on the filtering suggestion being a valid alternative in all cases. Extension methods, as mentioned in a previous post, may work here too, but still aren't optimal in my opinion.

Matt

Just to elaborate on the previous comment, I'm using a trivial example to highlight the common need to filter out records without having developers implement WHERE statements all over the system.

When just IsActive = true is a requirement, that's no huge overhead, but what about (where IsVerified = true AND IsActive = true AND IsNotLockedOut = true)?

Ayende Rahien

Matt, I gave several example of how you can modify that using different methods, NHibernate, RavenDB, etc. Most OR/M has some way to do those sort of things.

For the scenarios that you posit, NHibernate has support for filters, so it isn't a static decision, you can add/remove them.

Matt

Aren't filters globally applied though? In which case, filters don't work if you want to expose the reverse but force it to be explicitly used instead of as the default?

Don't get me wrong - I absolutely see your point that in most cases repositories are overkill in the NHibernate world, but I do disagree with the premise that there is no room for abstraction to another layer for certain applications.

I'm still not convinced there is an absolute for either approach, instead the best approach lies somewhere in the middle.

Ayende Rahien

Matt, I never said that there isn't a need to abstract some things out. What I said was that there isn't a need to do that in the common case. In a typical app, you have cause to abstract 5% - 10% of the data access, because it is complicated / ugly.

The rest is trivial , and should be treated as such

Matt

We're arguing the same thing then - except we have differing views of what should be abstracted and what is not.

You argue this should NOT be abstracted:

http://ayende.com/blog/153153/northwind-starter-kit-review-refactoring-to-an-actual-read-model

I say it probably should. I guess it all boils down to a matter of opinion.

Funnily enough, this is something I've been wrestling with myself for some time now, so these posts are pertinent to me personally - thanks for the frequent posts and I hope they keep coming.

Marco

Ayende

How do you control caching data when exposing ISession/IDbContext directly to your controllers when for example your working within a team environment? each team member would not know that the other person is storing the data in cache unless scanning the files.

Ayende Rahien

Marco, Caching is something that you do for a specific scenario, this isn't something that you do globally. Therefor, you don't care what someone else is doing

Ignacio Fuentes

@Ayende,

I dont think EF Code First supports that kind of default filtering.

http://stackoverflow.com/questions/6932209/how-can-i-have-entity-framework-return-related-objects-with-some-defaults

Benny Michielsen

@Matt

You can add something specificationesque to solve the problem at hand. Throw the isession/idbcontext in a getactiveroot class which adds the filter

Matt Hidinger

@Ignacio Fuentes,

I wrote a post just for you, to describe how I handle this type of filtering in my EF infrastructure:

http://www.matthidinger.com/archive/2012/01/25/a-smarter-infrastructure-automatically-filtering-an-ef-4-1-dbset.aspx

John

"With RavenDB, you can define that inside a query listener." Link please?

Matt Warren

@John

See the docs here http://old.ravendb.net/documentation/triggers/read

Karep

Ayendt I'm rewatching Hibernating Rhinos #9 and you do exactly what you now say is wrong. You show how to create repositories. And you do use ORM with those repositories. A lot changed in your practices I see.

Ayende Rahien

Karep, Indeed, practices change over time, based on actual experience in the field and seeing what works and what doesn't work.

Karep

Thanks for response. Now it's clear. Sometimes seems that you contradict yourself but I should probably take into account that some posts are from long time ago.

Comment preview

Comments have been closed on this topic.

FUTURE POSTS

  1. Paying the rent online - 22 minutes from now
  2. Reducing parsing costs in RavenDB - about one day from now

There are posts all the way to Aug 04, 2015

RECENT SERIES

  1. Production postmortem (5):
    29 Jul 2015 - The evil licensing code
  2. Career planning (6):
    24 Jul 2015 - The immortal choices aren't
  3. API Design (7):
    20 Jul 2015 - We’ll let the users sort it out
  4. What is new in RavenDB 3.5 (3):
    15 Jul 2015 - Exploring data in the dark
  5. The RavenDB Comic Strip (3):
    28 May 2015 - Part III – High availability & sleeping soundly
View all series

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats