问题
Suppose I have this relationship:
abstract class Base { int Id; int JoinedId; ... }
class Joined { int Id; int Discriminator; ... }
class Sub1 : Base { ... }
class Sub2 : Base { ... }
for the following tables:
table Base ( Id int, JoinedId int, ... )
table Joined ( Id int, Discriminator int, ... )
I would like to set up a table-per-hierarchy inheritance mapping for the Base, Sub1, Sub2 relationships, but using the Disciminator property from the Joined class as the discriminator.
Here's the general idea for the mapping file:
<class name="Base" table="Base">
<id name="Id"><generator class="identity"/></id>
<discriminator /> <!-- ??? or <join> or <many-to-one>? -->
<subclass name="Sub1" discriminator-value="1">...</subclass>
<subclass name="Sub2" discriminator-value="2">...</subclass>
</class>
Is there any way of accomplishing something like this with the <discriminator>
, <join>
, or <many-to-one>
? NHiberante seems to assume the discriminator is a column on the given table (which makes sense to me.. I know this is unorthodox).
Thanks.
回答1:
Can't you use a discriminator-formula with a subselect on Joined
?
<discriminator formula="(select j.discriminator from Joined j where j.id = joinedid)">
回答2:
I was looking for the exact same thing and after seeing Diego's post I assumed it wasn't possible and went on with searching Google trying to find alternatives. But after finding a functioning solution through trial and error I realized it's the exact same solution posted above by Meriton. The caveats I came across however (which he accounts for but doesn't explain) is that you must fully qualify your field in the forumla, you must only return one field, and you must wrap your formula in parenthesis. If you leave the table name out of the field name, it will assume it's a field on the current table the query is for and will get prefixed with something like MyTable0_1.
Which will break your query. The parenthesis are required to have it render out like a nested select statement. Using a formula will determine the value of your discriminator field to compare to the discriminator value in your subclass. When I checked my SQL being sent I found that it essentially gave me this... (note my discriminator field was a uniqueidentifier)
....WHERE client0_.Id=@p0 and (SELECT ClientTypes.ClientClassId FROM ClientTypes WHERE ClientTypes.TypeId = client0_.TypeId)='f04c03db-d469-4c01-83c5-5a19c0aea264'
Hope this helps others with this problem.
回答3:
Short answer is: it can't be done, unless you use a view as the table.
I've had the same problem in my current project, and I had to work around it using a strategy pattern.
来源:https://stackoverflow.com/questions/2740128/discriminator-based-on-joined-property