ManyToOne() with InnerJoin on Custom Column - nhibernate

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.

Related

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);

How do I map an optional one-to-one relationship with Fluent NHibernate?

I've got two entities, one called Site and the other called Assignment. A Site may or may not have an associated Assignment. An Assignment is only ever associated with one Site. In terms of C#, Site has a property of type Assignment which could hold a null reference.
I have got two tables by the same names in the database. The Assignment table's PK is also its FK back to the Site table (rather than Site having a nullable FK pointing to Assignment). The SQL (with fields omitted for brevity) is as follows
CREATE TABLE Site(
SiteId INT NOT NULL CONSTRAINT PK_Site PRIMARY KEY)
CREATE TABLE Assignment(
AssignmentId INT NOT NULL CONSTRAINT PK_Assignment PRIMARY KEY,
CONSTRAINT FK_Assignment_Site FOREIGN KEY (AssignmentId) REFERENCES Site (SiteId))
I'm using Fluent NHibernate's auto persistence model, which I think I will have to add an override to in order to get this to work. My question is, how do I map this relationship? Is my schema even correct for this scenario? I can change the schema if needs be.
You need to read these:
http://ayende.com/Blog/archive/2009/04/19/nhibernate-mapping-ltone-to-onegt.aspx
http://gnschenker.blogspot.com/2007/06/one-to-one-mapping-and-lazy-loading.html
https://www.hibernate.org/162.html
it's not possible to have one-to-ones lazy loaded unless they are not-nullable, or you map them as a many-to-one with one item in it

Fluent-NHibernate table mapping with no primary key

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.

How to Add a Many-To-Many Relation in Entity Framework

I am a newbie. I have been able to Add new entities where there is a One-To-Many Relation. I am having a problem (don't Know how to do it) adding a new Entity when the relation is using Many-To-Many.
In my EDM I have:
Orgs
<Scalar Properties>
a. Org_ID (Identity Field)
b. OrgName
c. OrgDesc
<Navigation Properties>
Building_orgs_Relation
Buildings
<Scalar Properties>
a) Building_ID (Identity Field)
b) Building_Desc
<Navigation Properties>
Building_orgs_Relation
Org_Building_Relation
a) Building_org_ID (Identity Field)
b) Org_ID
c) Building_ID
<Navigation Properties>
Building
Org
I want to:
Insert New Orgs
Delete Existing Org
Reassign Org To different Building
Update Org
Can some please provide a sample on how to do it using the mentioned EDM?
VB code will be appreciated.
Right now, the Entity Framework is really limited in terms of what kind of many to many relationships it can handle. The only thing that the Visual Studio designer will recognize is a table consisting of only two columns, both foreign keys to the other two tables, and where the primary key is a compound key on both of the foreign keys.
So, if you have control of your database schema, one thing you could do is change your Org_Building_Relation table to drop the Building_org_ID column and make the primary key a compound key on Org_ID and Building_ID. If you do that, then when you map the tables the Entity Framework will recognize this as a many to many relationship.
If you can't do that (e.g., you don't have control of the database schema), then you will need to make sure that the only fields that you map in your EDMX are the fields which relate to the other tables, and that you do not map the primary key. This is difficult, because the mapping wizard will discard and re-create the storage mapping every time you update.
Another option would be to not use a "proper" many to many mapping in the Entity Framework and instead just treat the relationship as another entity instead of having it subsumed into the relationship.
I can't remember if this has been improved in the forthcoming .NET 4.0.