I have a table that needs relations to 2 tables, according to ObjectType column.
For example if ObjectType=1 then column Object should point to TABLE1, and if ObjectType=2 then point to TABLE2.
Can I accomplish this in NHibernate mappings or as Fluent NHibernate?
If not will you suggest me using same Interfaces for both Table classes? (Note: table schemas are totally different)
Why not reference both tables, and use one or the other according to your needs in the class code?
Use a property that returns a common interface for both tables and gives one table or the other according to the object type.
Related
I’m in a dilemma choosing the best strategy to model my database.
Let’s say I have a two tables: Variable(ID) and Object(ID).
Now, an entry in Variable may reference another entry in Variable or in Object.
To model this, one approach is creating 2 mapping tables:
Variable_Variable(variable_id, variable_id), Variable_Object(variable_id, object_id)
The other approach is to have in the Variable table two reference columns:
Variable(ID, parent_variable_id, parent_object_id).
If this variable references another variable, then the parent_object_id is null and vice-versa.
I feel first approach is neater, but second approach is faster when querying the database.
Is there any standard to apply in this cases? Which is the usual approach for these cases?
Thanks,
Danny.
Given that all relations are 1:1 I would go with your second approach of having parent_variable_id and parent_object_id columns in your Variable table.
You could then have a CHECK constraint to ensure that only one or the other column contains a value (or neither, if your variables don't have to reference a parent).
Another alternative that you didn't mention is using a single mapping table MappingTable (variable_id, parent_variable_id, parent_object_id). The downside with this is that, if variables must have a parent, you will then have to enforce a 1:1 relationship between the Variables table and Mappings table.
I would only consider using a mapping table if modelling an n:n relationship, or if there is additional information about the relationship between a variable and it's parent that needs to be recorded.
I have a mapping in FluentNHibernate for a HasMany relationship and I'd like to specify a Table on it to override the default Table that nHibernate will look in to find those objects that I have many of. Does that make sense?
So lets say I have a table for Invoices and a table for InvoiceItems and lets say I have table called InvoiceItemsTwo.
I have a class for Invoice and a Class for InvoiceItems as well, and their mappings are pretty straight forward. I'd like to specify in my mapping for Invoice, that it should look for it's items in InvoiceItemsTwo instead of the default InvoiceItems.
So my mapping of that relationship looks like this
HasMany(c => c.InvoiceItems).Cascade.SaveUpdate().Table("InvoiceItemsTwo");
But this doesn't work. I keep getting an error from my website at runtime that says Invalid object name 'InvoiceItems'.
Why is it ignoring the fact that I am explicitly specifying the Table in my mapping on the relationship?
I tried dumping the mapping at run time and it's being setup something like this
<bag cascade="save-update" table="InvoiceItemsTwo">
Any ideas?
The table attribute applies only to many-to-many relationships, not one-to-many.
you can't specify a different table in your mapping class. Fluent NHibernate uses the class mapped on the property list (InvoiceItems).
If yoy want to use another class to map your details table you must create a InvoceItemsTwo class and map it in your master table class.
You could map the list as composite-element instead of a one-to-many relation and then map it to another table. But it is not a good idea. Consider that NH needs to know where to store an object which is in memory. So it may happen that the object is stored in the wrong table.
Either store all the InvoiceItems in separate tables using composite-element instead of one-to-many and components instead of many-to-one (however this is called in Fluent).
Or store all the InvoiceItems in the same table and use regular references.
I have two tables:
call_records
crm_call_records
call_records do not know that crm_call_records and their corresponding classes exists in different assemblies. I can therefore not add a subclass mapping in the mapping file for call_records.
crm_call_records has a column named call_record_id which contains the value of the PK in call_records.
How should the mapping files look like?
It doesn't matter what assembly your classes are in.
If the subclasses are defined by records in a different table with the PK pointing to the parent class' id, then you have a table per subclass strategy.
Currently I have a table "ComponentAnalysis" and a table "HistoryOfUse" that I am trying to map in Fluent NHibernate.
A component analysis should only have 1 history of use and a history of use should belong to 1 component analysis. This would suggest to me that the tables should be set up for a 1 to 1 mapping. But the designer of the DB didn't set it up that way.
Instead "HistoryOfUse" has a column "ComponentAnalysisID" to specify what component analysis it belongs to. To conform to the database I should have HistoryOfUse References ComponentAnalysis and ComponentAnalysis should HasMany HistoryOfUse.
But if I do this then I need to have a list of type HistoryOfUse which seems fairly annoying. Is there a way to set this up, without changing the database, to allow ComponentAnalysis to have a single HistoryOfUse object even though, according to the DB structure, it should have a list of them?
You can use HasOne method to map your classes. Here is the detailed article about this.
Your class ComponentAnalysis will "HasOne(x => x.HistoryOfUse)". Column HistoryOfUse.ComponentAnalysisID should be a unique key and a foreign key referenced to the ComponentAnalysis.ID column.
In my domain model I have an abstract class CommunicationChannelSpecification, which has child classes like FTPChannelSpecification, EMailChannelSpecification and WebserviceChannelSpecification. Now I want to create an HQL query which contains a where clause that narrows down the result to certain types of channel specifications. E.g. (in plain English) select all CommunicationChannelSpecifications that whose types occur in the set {FTPChannelSpecification, WebserviceChannelSpecification}.
How can this be achieved in HQL? I'm using NHibernate 2.0.1 and a table per subclass inheritance mapping strategy...
Thanks!
Pascal
Not positive in NHibernate, but in Hibernate, there are two special properties that are always referenced id and class. So, for your particular case, I'd do
from CommunicationChannelSpecifications spec where spec.class in (?)
NHibernate supports the same syntax as Hibernate in this case. See here for an example.