How to map many columns from one table in database to one array/list in class? - nhibernate

I have a table in database which has some columns like year,name and also 12 columns (m1,m2,...,m12) representing months. I would like to map this table into one class using NHibernate, ideally, these 12 mapped columns would look like:
_mappedMonths[] = new double[12];
Has anyone a solution for this ?

If you really want to map the columns directly to an array, as you describe, take a look at the ICompositeUserType interface. You can find an article about custom NHibernate mapping here, and this blog post might be of interest as well.
However, if it is not super important you might consider mapping the columns just as you normally would, but as private/protected properties, and then create a public property in your class that exposes those private/public properties as an array. That would be a simpler and faster solution, but would result in code that is not quite as clean.

Related

Class that represents parts of another object?

I have a class called "EntryData" with a couple of fields in it, "name", "entrydate", "enteredby" and "key" a foreign key. The key points to the "DataEntered" class with "key", "startdate", "enddate" and "values", an array of doubles. This matched the layout of a db we were using, which stored data in two tables.
Now we are adapting this to a db that stores all the same data, but in a single table. We would like the API to remain the same.
So, I hope this makes sense:
Can I make a new class called "DataEntered" that has no instances its own, and consists solely of pointers to particular fields in "EntryData"? That is, there would be no objects of this class, it would simply be a sort of wrapper that always referred to the underlying EntryData it was called on, like this…
myEntryDataInstance.DataEntered.startdate
In this case there is no instance of DataEntered.
The easy way to solve my problem would be if I could put periods in my method names, but that doesn't seem to work. :-)
What your asking for is called inheritance but VB does not allow you to inherit from multiple classes. You would have to inherit from one class and then write in pointers to the second class which would have to be saved as a variable in your class.
Problem is, what do you plan to do with this? Are you using the Entity Framework or your own homebrewed data manager? If you are using something gereric, it won't know how to handle you NEW class with multiple tables.

NHibernate queries return multiple copies of the target objects

I have two classes mapped in NHibernate: Dragon and its subclass FierceDragon, with a few FierceDragons stored stored in a table called Dragons. When I run an HQL query like from Dragon... I get back two objects per row: the expected FierceDragon and an ordinary Dragon that's a copy of the FierceDragon (insofar as is possible; naturally it lacks the FierceDragon's extra Ferocity and TimeSinceLastMeal properties). In particular, their IDs are identical. When I do from FierceDragon I get only FierceDragons, with no extra copies, but that won't work for me in general.
Why does this happen, and how can I prevent it?
If you create your mapping correctly, that should not pose a problem.
There are 3 different ways of mapping a class-hierarchy to the DB using NHibernate.
Check out this and this article.
You can map both Dragon and FierceDragon to the same table, but, in that case, your table should have some nullable columns to be able to store the additional properties of FierceDragon. Since you're talking about one table, I suppose you want to use the 'Table per class hierarchy' mapping strategy ?
The mystery is solved; I thought I was only mapping FierceDragon, but no, I was mapping Dragon too, both to the table Dragons. Not sure why NH did that particular thing in this case, but clearly the fix is to, you know, not map separate classes to the same table. Or if you do, at least give NH some way of distinguishing between the two in the DB.

Storing polymorphic objects in SQL database

[noob warning!] I need to store some data in some tables where it is like the equivalent of an array of pointers to polymorphic objects. E.g. (pseudo C++)
struct MyData { string name; }
struct MyDataA : MyData { int a,b,c; }
struct MyDataB : MyData { string s; }
MyData * data[100];
I don't really know what google search to enter! How would you store info like this in an SQL database?
My random thoughts:
I could have one table with a column that is the struct identifier and then have redundant columns, but this seems wasteful.
I can have one table for each struct type. These would have a foreign key back to the master array table. But, how do I point to the struct tables?
There's really two major ways to solve this:
table-per-type
table-per-hierarchy
Either of them has its pros and cons.
Table-per-type gives you more tables (one per type), which only store the "delta" from the immediate super class. Worst case, you need to join together a number of tables to finally get all the data together for a single instance of a type. Pros: since you only store what's really relevant for that type into a separate table, you can do this like set NOT NULL restrictions etc. on the database table.
Table-per-hierarchy gives you less tables, but each table represents an entire hierarchy, so it will contains potentially lots of columns which aren't filled (in the rows representating base class types). Also, on the extra columns that make up the derived classes, you cannot set things like NOT NULL restrictions - all those extra columns must be nullable, since they really don't exist in the base classes, so you loose some degree of safety here.
See for yourself - there are two really good articles on how to do this (in Entity Framework, but the principles apply to any database and any data mapping technology):
Demystifying The Code: Table Per Type
Demystifying The Code: Table Per Hierarchy
Hope this helps and gives you some inputs!
Marc
I do the "table-per-sublcass" style from the Hibernate docs.
You make a Person table with all the things you know about a person, plus the PersonID. Then you make a Customer table, with only the data that's unique to a Customer (account balance, etc). Put the PersonID in the Customer table. A WebsiteUser might have a CustomerID in it, and so on down the chain.
One-to-one relationships mapping the IS-A inheritance relationships.
One possibility is an XML field to store the data, this allows searching and retrieving whilst also being relatively easy to serialise. (the question says SQL, but doesn't specify a specfic vendor database, so XML may not work for every DB solution.)
Edit : I'm going to caveat this because it's not entirely clear what needs to be stored / retrieved / purpose etc, so XML may be entirely inappropriate - I'm throwing it out there as a thought provoker instead.

Fluent Nhibernate and Dynamic Table Name

I've got a parent and child object. Depending on a value in the parent object changes the table for the child object. So for example if the parent object had a reference "01" then it will look in the following table "Child01" whereas if the reference was "02" then it would look in the table "Child02". All the child tables are the same as in number of columns/names/etc.
My question is that how can I tell Fluent Nhibernate or nhibernate which table to look at as each parent object is unique and can reference a number of different child tables?
I've looked at the IClassConvention in Fluent but this seems to only be called when the session is created rather than each time an object is created.
I found only two methods to do this.
Close and recreate the nhibernate session every time another dynamic table needs to be looked at. On creating the session use IClassConvention to dynamically calculate the name based on user data. I found this very intensive as its a large database and a costly operation to create the session every time.
Use POCO object for these tables with custom data access.
As statichippo stated I could use a basechild object and have multiple child object. Due to the database size and the number of dynamic table this wasn't really a valid option.
Neither of my two solutions I was particularly happy with but the POCO's seemed the best way for my problem.
NHibernate is intended to be an object relational mappers. It sounds like you're doing more of a scripting style and hoping to map your data instead of working in an OOP manner.
It sounds like you have the makings of an class hierarchy though. What it sounds like you're trying to create in your code (and then map accordingly) is a hierarchy of different kinds of children:
BaseChild
--> SmartChild
--> DumbChild
Each child is either smart or dumb, but since they all have a FirstName, LastName, Age, etc, they all are instances of the BaseChild class which defines these. The only differences might be that the SmartChild has an IQ and the DumbChild has a FavoriteFootballTeam (this is just an example, no offense to anyone of course ;).
NHibernate will let you map this sort of relationship in many ways. There could be 1 table that encompasses all classes or (what it sounds like you want in your case), one table per class.
Did I understand the issue/what you're looking for?

Map dynamic/generic properties with NHibernate

I have a scenario where I have a propertybag of key/values that would look something like:
Entry 1 : key="Load", value="2", type="int"
Entry 2 : key="DailyStatus", value="0", type="bool"
I am trying to figure out if it's possible with nhibernate to map these values to a single table that I can pull out at a later time into .net simple types.
I am trying to avoid creating classes to contain all of this data as it can be very repetitive and doesn't allow portions of the application to be as flexible as possible. I had considered storing it in XML or JSON, but this data has to be queried against on a pretty regular basis.
Has anyone mapped dictionaries of simple types to a table in nhibernate and pulled the data back out? I suppose mapping to a generic dictionary would work:
IDictionary<string, IDictionary<object, Type>>
I can do it by hand, but if there is a builtin way for nhibernate to accomplish it that would be easier.
How about you create a class "Triplet" with attriutes id, key, value, type and then map it to a table called whatever you want?