0

When using ReferencesAny<> there is .EntityTypeColumn("MyType") which is not visible to application. Is there option to query by that column using HQL or something and how to integrate into my LINQ to HQL queries?

Andrej Kaurin
  • 11,592
  • 13
  • 46
  • 54

2 Answers2

1

As always, NHibernate has solution for (almost) everything.

Let's assume mapping like this (ala documentation):

ReferencesAny(x => x.AnyEntity) // the property name is AnyEntity... used below

   // some explicit mapping
   .AddMetaValue<Household>(typeof(Employee).Name)
   .AddMetaValue<Client>(typeof(Contact).Name)

   // the essence of <any>
  .EntityTypeColumn("MyType")
  .EntityIdentifierColumn("TheId")
  .IdentityType<int>();

A cite from doc: 14.7. The where clause:

Likewise, the special property class accesses the discriminator value of an instance in the case of polymorphic persistence. A .Net class name embedded in the where clause will be translated to its discriminator value.

So, now we've informed NHibernate, that the colunn MyType contains the type, the equiv of the C# type. Because we can access EntityTypeColumn via the .class - this query will give us what we want:

// the 'Contact' represents the value contained in DB...
var hql = "from MyEntity where AnyEntity.class = 'Contact' "; 
...
session.CreateQuery(hql)
        .List<MyEntity>();

this will generate the WHERE ... MyType = 'Contact'

The same in the QueryOver:

var query = session.QueryOver<MyEntity>()
     .Where(x => x.AnyEntity is Contact)
     .List<MyEntity>();

NOTE: the bad news, that with built in LINQ provider, similar query is failing. I would guess it is a bug. I.e. this is not working session.Query<MyEntity>().Where(x => x.AnyEntity is Contact), generating the wrong WHERE clause

EXTENDED as asked in the comment

We can also filter by the <any> elements ID, the 'EntityIdentifierColumn'

The syntax would look like this (see the magical ".id" selector")

query
  ...
  .Where(Restrictions.In("AnyEntity.id", new[] {1, 2, 3, 4, 5, 6, 7, 8}))
  ...
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
0

How about simply mapping the column in the entity you reference. Have a base class for all kind of types for example?

MichaC
  • 13,104
  • 2
  • 44
  • 56
  • Not sure what you think. Could you add some sample. Just quick one? – Andrej Kaurin Jan 04 '14 at 00:04
  • I mean if you want to access that column, you just have to add a property to your entity which get referenced by ReferencesAny and map the column to that property... – MichaC Jan 04 '14 at 00:20
  • Ah yes..got it. However, is there still a way to do this with HQL and integrate with LINQ to HQL? – Andrej Kaurin Jan 04 '14 at 00:53
  • as far as I know hql or all other query types in NH only support the entities you have mapped. Meaning no. – MichaC Jan 04 '14 at 00:54