Fluent-NHibernate table mapping with no primary key - fluent-nhibernate

I am trying to create a mapping to a database table that has no primary keys/references.
public class TestMap : ClassMap<<Test>Test> {
public TestMap() {
WithTable("TestTable");
Map(x => x.TestColumn);
}
}
This fails and expects id or composite-id. Is this possible in fluent nhibernate?

In Oracle at least, I have used "ROWID" for this. For mssql you might use the "ROW_NUMBER()" builtin function for readonly access to the table, but I haven't tried that...

No. You'll have to add a surrogate primary key, such as an identity column in SQL Server, to map this table. As far as I know, this isn't supported by NHibernate itself.
Why don't you have a primary key on this table?

This functionality isn't supported by nhibernate as far as I know. As a general rule of thumb, however, you should really always have some kind of ID and if you find yourself in a situation where you think you don't need one you should assess your data model. An ID, whether it be a table-specific primary key, or a surrogate key from another table, should exist. This not only ensures that nhibernate can process the table, but helps performance via indexing.
Before you start assuming nhibernate isn't going to fulfill your needs, consider why you don't have a key on the table and what kind of sense it makes not to have one.

If we can bring a column from table having no primary key/identity coulmn, then we can use fluent as below:
Id(x => x.TempID).Column("TempID");

If the table contains data that belongs to another entity, you could map it as a collection of components. Components are not identified by themselves, but they belong to another entity, which is identified.

You can map an entity to a table without keys defined in the database. I do so in legacy SQL Server databases. However, the table must have a candidate key (some set of columns that actually stores a unique combination of values). The concept of entity involves the notion of some kind of identity.
Instead of this, what you're trying in your code is to map an entity without identity, wich isn't possible.

Related

Can I map a field #Id when it is not the id in the database?

I have a database table that has three fields: two of them are a composite key for the table, and the other one is an autogenerated field that is not the id of the table. When mapping this table to a JPA entity, can I map the autogenerated field as the #Id, even when it is not? If yes, what are the implications? Note: I cannot change the database.
Yes, you can. This is actually often the case when a Hibernate entity is mapped to a database view which is defined on top of multiple real tables (and other views).
If you don't intend to create new instances of that entity through Hibernate, then there are no implications (if the key is really unique of course).
If you will be persisting new instances with Hibernate, then be sure to pick the appropriate identifier generation strategy.
You should not - #Id has special meaning and will be used as the primary key by hibernate.
The #GeneratedValue annotation works only if #Id is also present, so you cannot use that on the non-id field. More details here - there are possible alternatives depending on which db you are using.

ManyToOne() with InnerJoin on Custom Column

Is there a way to map property with database column with custom column, that IS NOT a FK, just a candidate key ( it is unique for table )?
If not, what is my options here? (need to restrict select results with joined table restrictions)
NHibernate supports feature called property-ref. It is documented here: 5.1.10. many-to-one. Some extract:
The property-ref attribute should only be used for mapping legacy data
where a foreign key refers to a unique key of the associated table
other than the primary key. This is an ugly relational model. For
example, suppose the Product class had a unique serial number, that is
not the primary key. (The unique attribute controls NHibernate's DDL
generation with the SchemaExport tool.)
So, if the child table contains for example Guid, which is the same as in the target parent table... this could solve the issue. Example mapping:
<many-to-one name="Parent" property-ref="ParentGuid" column="THE_GUID_COLUMN"/>
Using the fluent syntax, it could look like this:
References(x => x.Parent)
...
.PropertyRef("ParentGuid")
.Column("THE_GUID_COLUMN");
Anyhow, this is not ideal and should be used mostly for solving legacy stuff.

Fluent Nhibernate mapping Legacy DB with composite key

I am using Fluent NHibernate (which I am fairly new to) in an application I am developing using a legacy Oracle DB. The DB has composite keys which are comprised of foreign keys and database generated columns. The generated columns are supplied by calling a DB function with the table name, and one of the other foreign key parts. The generated composite key parts are not unique, and I cannot change this. The generated key parts are often used as foreign keys on other tables too.
If I create entity mapping which specifies the composite key as it is in the database, then we cannot use any identity generation strategies, which breaks unit of work
If I create entity mapping which specifies only the generated column as the primary key, then I can use trigger-identity to generate the ids, and I get unit of work, but I then have a problem when I want to update, or access a child collection: The other parts of the key are not included in the WHERE statement.
Can anyone give me any advice on how to proceed?
If I stick with mapping composite keys, can I extend nhibernate to output the SQL to use trigger-identity? If so, can you suggest a starting point?
If I map a single column key, can I include other properties in a WHERE clause for HasMany mapping and Updates?
Unfortunately, as you have already found out, there is no support at all for this setup.
My suggestion is to do INSERTS manually (using custom SQL, for example). And yes, this breaks the UoW, but that is true of identity too.

NHibernate - how to configure associations not to use primary key

I'm working with a legacy database put together by some very strange people. I'm writing an NHibernate DAL over the top of it but running into some odd mapping scenarios.
In one example, I have a table with a number of fields including LE_RECNUM (integer primary key) and LE_CODE (string).
However, all relationships throughout the database join onto LE_CODE, not LE_RECNUM, for some unfathomable reason.
I need to specify that LE_RECNUM is the Id in my mapping file, because I need the primary key to be generated when I insert records. However, I want all associations to use LE_CODE instead of LE_RECNUM.
Can anyone suggest how I might do this?
References(x => x.SomeProperty).Column("LE_CODE").PropertyRef(x => x.SomePropertyInParent);

Is it beneficial to use multicolumn (composite) primary keys when using Linq to SQL?

Is it beneficial to use multicolumn (composite) primary keys for a many to many relationship table when using Linq to SQL?
Or should I just add an identity column as a non-clustered primary key and index the FK columns appropriately?
Not a LINQ issue. If you need them for your schema, then use them. If you don't, don't. Either way, LINQ will handle your schema just fine.
One area that LINQ to SQL doesn't handle well are multy column / key mapping table that are used to connect a many to many relationship but I wouldn't say this strickly falls under the category that your question addresses. You can still perform CRUD operations on a mapping table within LINQ but LINQ cannot walk the relationship presented by a many to many mapping table. (LINQ works fine with one to one and one to many tables.)
I can't speak to any issue with the Entity Framework but again, I would be very surprised if the EF had any issues with multi-column / multi-key tables.
If it makes sense in your domain to have a multi-column composite key, then use one. Otherwise use the usual identity column as the surrogate primary key.
EDIT: that was general advice and not taking into account any technical aspects of implementing using LINQtoSQL. These may be of interest:
How to: Handle Composite Keys in Queries (LINQ to SQL)
LINQ To SQL Samples
Linq to SQL DTOs and composite objects