2

Contrived example, but let's say I have a these entities:

public class Root
{
    public virtual Customer Customer { get; set; }
}

public class Customer
{
    public virtual CustomerData Data { get; set; }
}

public class CustomerData
{
    public virtual string FooName { get; set; }
}

Now, let's say I want to create a filter for Root based on the value of FooName. Intuitively, I tried this in my FooMap class. Using Fluent mappings.

ApplyFilter("FooNameFilter", "Customer.Data.FooName in (:argument)");

This doesn't work. A SqlClient.SqlException is thrown stating The multi-part identifier "Customer.Data.FooName" could not be bound.

Is there a way to make filters work this way, or am I forced to move that logic into all Query<Root>()s instead?

Samantha Branham
  • 7,350
  • 2
  • 32
  • 44
  • 1
    My bets are on having to move the logic into your queries. As I understand it, filters are SQL, not HQL, so you wouldn't be able to use that intuitive `Customer.Data.FooName` joining syntax. I think the filters have to just be about columns that are defined on that one table. – Daniel Schilling Aug 28 '13 at 03:32
  • That's what I'm afraid of. Doesn't screw me, but I really liked the filter API for what I was doing. – Samantha Branham Aug 28 '13 at 14:20

1 Answers1

1

What could be working, is to move the filter to the CustomerData object if possible, or to create "more sophisticated SQL condition" applied on the Customer mapping. But it is about pure SQL, no references. How do the filters work?

The filters are the same as the where clause, but could be adjusted in a runtime. The extract from documentation 18.1. NHibernate filters

NHibernate adds the ability to pre-define filter criteria and attach those filters at both a class and a collection level. A filter criteria is the ability to define a restriction clause very similiar to the existing "where" attribute available on the class and various collection elements. Except these filter conditions can be parameterized. The application can then make the decision at runtime whether given filters should be enabled and what their parameter values should be. Filters can be used like database views, but parameterized inside the application.

The definition of the where:

where (optional) specify an arbitrary SQL WHERE condition to be used when retrieving objects of this class

Other words, these settings act as "add on" to our mapping. They are extending it (both where and filter) with more SQL balast. The filter could be shared among many mappings and applied to all queries inside one session, but it must target the column:

condition=":myFilterParam = MY_FILTERED_COLUMN"
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
  • Given the error message, that's what I figured was happening under the covers. What I'm still not sure about is if I can make this work with filters. I'm not sure how filtering CustomerData helps when I want to filter queries against Root. I'm pretty new to NHibernate, so I'm not sure what all of my options are yet. – Samantha Branham Aug 28 '13 at 14:19
  • The essence of a Filter is mostly in the collection handling. You can have large collection, or dependent on a culture, user name etc. In these cases, it could be OK to use filter. You find out what is the restriction for current session (user culture) and you can set that to a session. All collections will be filtered with this setting. But in case, that you'd like to get a Customer, which has some setting... use Criteria or QueryOver api. You will "Join" the customer data and apply filter during querying – Radim Köhler Aug 28 '13 at 15:32
  • There are some links to this topic, when I tried to explain how to use filter: http://stackoverflow.com/a/17109300/1679310, http://stackoverflow.com/a/14378253/1679310 – Radim Köhler Aug 28 '13 at 15:34
  • Sounds like I'm misusing them then. Thanks! – Samantha Branham Aug 28 '13 at 20:42
  • Good if this could help anyhow ;) – Radim Köhler Aug 29 '13 at 03:04