Can I make discriminator properties available in entity class

Posts   
 
    
fpdave100
User
Posts: 97
Joined: 06-Feb-2012
# Posted on: 23-Feb-2012 09:59:51   

using v3.1, with NHibernate output using fluent mapping

I have some table per entity hierarchy inheritance, and a discriminator property, which is listed in the Fields for the entity, but which doesnt get code generated to the entity class itself. I'd like to be able to query this (in LINQ) for instance, and so would like it to be exposed.

How can i achieved this

Walaa avatar
Walaa
Support Team
Posts: 14994
Joined: 21-Aug-2005
# Posted on: 23-Feb-2012 10:39:01   

Discriminator field can't be generated in both the Parent type and the sub-types, the code won't compile if the same field appeared twice in an inheritance hierarchy.

You can query the type of the entity in LINQ, right?

fpdave100
User
Posts: 97
Joined: 06-Feb-2012
# Posted on: 23-Feb-2012 10:43:30   

Walaa wrote:

Discriminator field can't be generated in both the Parent type and the sub-types, the code won't compile if the same field appeared twice in an inheritance hierarchy.

You can query the type of the entity in LINQ, right?

I'm happy for it to just be in the base class (the "parent" type)

if I query the type, using something like

from bv in BK.BudgetValues where bv is BudgetValueLeaf select bv as BudgetValueLeaf;

where BudgetValueLeaf is one of the sub types, with a discriminator value of 2, say.

is this going to generate the correct SQL code for me?

Walaa avatar
Walaa
Support Team
Posts: 14994
Joined: 21-Aug-2005
# Posted on: 23-Feb-2012 11:22:19   

Oh you are using NHibernate, ....I'm not sure if this is supported by NHibernate. But as a workaround, you can add a property to the base entity, that returns a specific value based on the type (reverse engineering the discriminator) :> And use this property in the query.

fpdave100
User
Posts: 97
Joined: 06-Feb-2012
# Posted on: 23-Feb-2012 11:27:12   

Walaa wrote:

Oh you are using NHibernate, ....I'm not sure if this is supported by NHibernate. But as a workaround, you can add a property to the base entity, that returns a specific value based on the type (reverse engineering the discriminator) :> And use this property in the query.

Thats what I've done but I've had to add it directly into the NH mapping

Map(x => x.BudgetValueType).CustomType<enumBudgetValueType>().Not.Nullable().Access.CamelCaseField(Prefix.Underscore);

as this was not generated by LLBLGEN.

from the llblgen project file:

      <EntityDefinition Name="ABudgetValue" GroupName="BudgetValues" IsAbstract="true" InheritanceType="1" DiscriminatorValue="0" DiscriminatorValueType="2">
        <Fields>
          <Field Name="BudgetKeyId" Type="int" IsReadOnly="true" IsAutoCreated="true" FieldIndex="1">
:
          </Field>
          <Field Name="BudgetValueType" Type="int" IsReadOnly="true" IsDiscriminator="true" FieldIndex="10" />
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39877
Joined: 17-Aug-2003
# Posted on: 23-Feb-2012 12:27:44   

It's not public because it pollutes the class interface. Why not use the 'OfType' or 'is' or 'as' operators in the linq query? Those are meant for filtering on types in Linq queries. Not sure whether NHibernate's Linq provider can handle those though...

Frans Bouma | Lead developer LLBLGen Pro
fpdave100
User
Posts: 97
Joined: 06-Feb-2012
# Posted on: 23-Feb-2012 12:32:12   

Otis wrote:

It's not public because it pollutes the class interface. Why not use the 'OfType' or 'is' or 'as' operators in the linq query? Those are meant for filtering on types in Linq queries. Not sure whether NHibernate's Linq provider can handle those though...

I can understand it not being exposed by default, as normally its not necessary, but I'd like to get at it in some cases.

fpdave100
User
Posts: 97
Joined: 06-Feb-2012
# Posted on: 23-Feb-2012 16:25:53   

fpdave100 wrote:

Otis wrote:

It's not public because it pollutes the class interface. Why not use the 'OfType' or 'is' or 'as' operators in the linq query? Those are meant for filtering on types in Linq queries. Not sure whether NHibernate's Linq provider can handle those though...

I can understand it not being exposed by default, as normally its not necessary, but I'd like to get at it in some cases.

It does seem as tho its not easily supported by NH either, as I'm now getting run-time errors

Walaa avatar
Walaa
Support Team
Posts: 14994
Joined: 21-Aug-2005
# Posted on: 24-Feb-2012 08:51:16   

So If this turned out to be not easily supported by NHibernate, then I think we don't have much to do about it.

fpdave100
User
Posts: 97
Joined: 06-Feb-2012
# Posted on: 24-Feb-2012 10:22:54   

Walaa wrote:

So If this turned out to be not easily supported by NHibernate, then I think we don't have much to do about it.

its not straight forward, but does appear to be possible, and it does seem to work, it must just be set as ReadOnly simple_smile

DiscriminateSubClassesOnColumn("[BudgetKeyType]");
Map(x => x.BudgetKeyType).ReadOnly().Not.Update().CustomType<enumBudgetKeyType>().Access.CamelCaseField(Prefix.Underscore);
daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 26-Feb-2012 23:10:23   

If it is really needed, you can slightly modify the template or create your own templateBindings to override the default template. For more info Read the sdk docs.

  1. Open your LLBLGen Project
  2. Select Windows->Show Template Bindings Viewer
  3. Select your current fluent binding, then edit the SD_NHibernateEntityFluentMapping template.
  4. Go to line 400. There it's a foreach statement which selects the fields to map. It looks like this:
foreach(IFieldElementCore field in entity.Fields.Where(
   f=>!f.IsPartOfIdentifyingFields && !f.IsForeignKeyField  
   && f!=entity.DiscriminatorField 
   &&   (f.FieldType.KindOfType!=FieldTypeKind.ValueTypeDefinition) 
   &&    (f!=versionField))
   .OrderBy(f=>f.Name))

.. and remove the discriminator condition:

foreach(IFieldElementCore field in entity.Fields.Where(
   f=>!f.IsPartOfIdentifyingFields && !f.IsForeignKeyField  
   &&   (f.FieldType.KindOfType!=FieldTypeKind.ValueTypeDefinition) 
   &&    (f!=versionField))
   .OrderBy(f=>f.Name))

This makes that the discriminator field would me mapped (also the ReadOnly is emitted). This is not fully tested and not officially supported, so you have to make sure it works for you.

David Elizondo | LLBLGen Support Team