fluent NHibernate one-to-one relationship? - fluent-nhibernate

I have a problem with one-to-one relationships in the fluent nHibernate.
I have the following relational table from the AdventureWorks2008 database.
BusinessEntity (Table)
BusinessEntityId Int (PK, Identity)
Person (Table)
BusinessEntityId int (PK, Reference with BusinessEntity table)
FullName varchar(255)
The relationship between BusinessEntity table and Person table is one-to-one.
How do I map fluently without any extra field like "Id" in the Person table?
There should be 2 class one for Person and another for BusinessEntity, or an appropriate model to best describe the above relation.
Thanks,
Ashraf.

presuming your Person mapping is pretty standard, the way you do this is by saying:
Id(x => x.BusinessEntityId)
.GeneratedBy.Foreign("BusinessEntity");
on the Person class.
This presumes that your Person class has a property called BusinessEntity which is of type BusinessEntity.
You'll also need to map BusinessEntity to Person with constrained set to true (to say that they primary key of Person is a foreign key reference to BusinessEntity).
The key thing is the GeneratedBy.Foreign() to say that your identity is generated by a link to another class.

Related

query with SQL m:n relationships

I have a quick question with respect to many to many relationships in sql.
So theoretically i understand that if 2 entities in an ER model have a M:N relationship between them, we have to split that into 2 1:N relationships with the inclusion of an intersection/lookup table which has a composite primary key from both the parent tables. But, my question here is , in addition to the composite primary key, can there be any other extra column added to the composite table which are not in any of the 2 parent tables ? (apart from intersectionTableId, table1ID, table2ID) a 4rth column which is entirely new and not in any of the 2 parent tables ? Please let me know.
In a word - yes. It's a common practice to denote properties of the relationship between the two entities.
E.g., consider you have a database storing the details of people and the sports teams they like:
CREATE TABLE person (
id INT PRIMARY KEY,
first_name VARCHAR(10),
last_name VARCHAR(10)
);
CREATE TABLE team (
id INT PRIMARY KEY,
name VARCHAR(10)
);
A person may like more than one team, which is your classic M:N relationship table. But, you could also add some details to this entity, such as when did a person start liking a team:
CREATE TABLE fandom (
person_id INT NOT NULL REFERENCES person(id),
team_id INT NOT NULL REFERENCES team(id),
fandom_started DATE,
PRIMARY KEY (person_id, team_id)
);
Yes, you can do that by modeling the "relationship" table yourself explicitly (just like your other entities).
Here are some posts about exactly that question.
Create code first, many to many, with additional fields in association table
Entity Framework CodeFirst many to many relationship with additional information

SQL relationship between a primary key column and the same column

In an existing SQL Server database, someone has defined the following:
Table Customer has a CustomerID column which is also identity. Then they have defined a relationship where Customer.CustomerID is primary key and Customer.CustomerID is also foreign key. I.e. the relationship points back to the same table and same column.
What is the purpose of this? Seems entirely pointless to me, so I plan to remove this relationship from the DB.
The relation is called a recursive association or reflexive relationship, you will need this type of relationship when you need to present a relationship between two or more elements of the same type.
For example: for presenting a relationship between employees, you could create two tables Employee and Manager. But because the manager is also an employee, you won't need two tables. So we create a recursive association that point for the same entity.
More about recursive association
UPDATE
Setting a column as PK and FK at the same time could also represent the concept of inheritance.
For example:
class Person {
int ID;
string name;
}
class Customer extends Person {
String workPlace;
}
That would result the tables Person and Customer as listed below:
Person
------------
int id (PK)
string name
Employee
--------------
int id (PK, FK)
string workPlace

Entity Framework not recognizing foreign key

Here's my table structure:
Person
PersonID int
Address
AddressId int
Address varchar
PersonAddress
PersonID int primary key references Person.PersonID
AddressID int primary key references Address.AddressID
As you can see there is no relation between Person and Address. When I add these 3 tables to EF 6.0, it does not add the PersonAddress table but adds a relationship between Person and Address. I am deeply confused.
EF is doing exactly what you want. In EF you have a relationship between OBJECTS, not SCHEMA. The object relationship between Person and Address can be accomplished without the need of a third object. This reduces the complexity and makes the code easier to manage. EF will handle translating the relationship back and forth to the schema as needed.

What is the necessity of junction tables?

I have implemented the following ways of storing relational topology:
1.A general junction relation table:
Table: Relation
Columns: id parent_type parent_id parent_prop child_type child_id child_prop
On which joins are not generally capable of being executed against by most sql engines.
2.Relation specific junction tables
Table: Class2Student
Columns: id parent_id parent_prop child_id child_prop
On which joins are capable of being executed against.
3.Storing lists/string maps of related objects in a text field on both bidirectional objects.
Class: Class
Class properties: id name students
Table columns: id name students_keys
Rows: 1 "history" [{type:Basic_student,id:1},{type:Advanced_student,id:3}]
To enable joins by the sql engines, it would be possible to write a custom module which would be made even easier if the contents of students_keys was simply [1,3], ie that a relation was to the explicit Student type.
The questions are the following in the context of:
I fail to see what the point of a junction table is. For example, I fail to see that any problems the following arguments for a junction table claim to relieve, actually exist:
Inability to logically correctly save a bidirectional relations (eg
there is no data orphaning in bidirectional relations or any
relations with a keys field, because one recursively saves and one can enforce
other operations (delete,update) quite easily)
Inability to join effectively
I am not soliciting opinions on your personal opinions on best practices or any cult-like statements on normalization.
The explicit question(s) are the following:
What are the instances where one would want to query a junction table that is not provided by querying a owning object's keys field?
What are logical implementation problems in the context of computation provided by the sql engine where the junction table is preferable?
The only implementation difference with regards to a junction table vs a keys fields is the following:
When searching for a query of the following nature you would need to match against the keys field with either a custom indexing implementation or some other reasonable implementation:
class_dao.search({students:advanced_student_3,name:"history"});
search for Classes that have a particular student and name "history"
As opposed to searching the indexed columns of the junction table and then selecting the approriate Classes.
I have been unable to identify answers why a junction table is logically preferable for quite literally any reason. I am not claiming this is the case or do I have a religious preference one way or another as evidenced by the fact that I implemented multiple ways of achieving this. My problem is I do not know what they are.
The way I see it, you have have several entities
CREATE TABLE StudentType
(
Id Int PRIMARY KEY,
Name NVarChar(50)
);
INSERT StudentType VALUES
(
(1, 'Basic'),
(2, 'Advanced'),
(3, 'SomeOtherCategory')
);
CREATE TABLE Student
(
Id Int PRIMARY KEY,
Name NVarChar(200),
OtherAttributeCommonToAllStudents Int,
Type Int,
CONSTRAINT FK_Student_StudentType
FOREIGN KEY (Type) REFERENCES StudentType(Id)
)
CREATE TABLE StudentAdvanced
(
Id Int PRIMARY KEY,
AdvancedOnlyAttribute Int,
CONSTRIANT FK_StudentAdvanced_Student
FOREIGN KEY (Id) REFERENCES Student(Id)
)
CREATE TABLE StudentSomeOtherCategory
(
Id Int PRIMARY KEY,
SomeOtherCategoryOnlyAttribute Int,
CONSTRIANT FK_StudentSomeOtherCategory_Student
FOREIGN KEY (Id) REFERENCES Student(Id)
)
Any attributes that are common to all students have columns on the Student table.
Types of student that have extra attributes are added to the StudentType table.
Each extra student type gets a Student<TypeName> table to store its specific attributes. These tables have an optional one-to-one relationship with Student.
I think that your "straw-man" junction table is a partial implementation of an EAV anti-pattern, the only time this is sensible, is when you can't know what attributes you need to model, i.e. your data will be entirely unstructured. When this is a real requirment, relational databases start to look less desirable. On those occasions consider a NOSQL/Document database alternative.
A junction table would be useful in the following scenario.
Say we add a Class entity to the model.
CREATE TABLE Class
(
Id Int PRIMARY KEY,
...
)
Its concievable that we would like to store the many-to-many realtionship between students and classes.
CREATE TABLE Registration
(
Id Int PRIMARY KEY,
StudentId Int,
ClassId Int,
CONSTRAINT FK_Registration_Student
FOREIGN KEY (StudentId) REFERENCES Student(Id),
CONSTRAINT FK_Registration_Class
FOREIGN KEY (ClassId) REFERENCES Class(Id)
)
This entity would be the right place to store attributes that relate specifically to a student's registration to a class, perhaps a completion flag for instance. Other data would naturally relate to this junction, pehaps a class specific attendance record or a grade history.
If you don't relate Class and Student in this way, how would you select both, all the students in a class, and all the classes a student reads. Performance wise, this is easily optimised by indices on key columns.
When a many-to-many realtionships exists without any attributes I agree that logically, the junction table needn't exist. However, in a relational database, junction tables are still a useful physical implmentaion, perhaps like this,
CREATE TABLE StudentClass
(
StudentId Int,
ClassId Int,
CONSTRAINT PK_StudentClass PRIMARY KEY (ClassId, StudentId),
CONSTRAINT FK_Registration_Student
FOREIGN KEY (StudentId) REFERENCES Student(Id),
CONSTRAINT FK_Registration_Class
FOREIGN KEY (ClassId) REFERENCES Class(Id)
)
this allows simple queries like
// students in a class?
SELECT StudentId
FROM StudentClass
WHERE ClassId = #classId
// classes read by a student?
SELECT ClassId
FROM StudentClass
WHERE StudentId = #studentId
additionaly, this enables a simple way to manage the relationship, partially or completely from either aspect, that will be familar to relational database developers and sargeable by query optimisers.

Model one-to-many relationship in database

I am trying to find a proper pattern to model one-to-many relationship from several tables to a common table.
EntityA, EntityB and other entities have one or many GenericInfo.
EntityA (0..1) ------ (1..N) GenericInfo
EntityB (0..1) ------ (1..N) GenericInfo
EntityC (0..1) ------ (1..N) GenericInfo
Option1: These entities are different so I cannot use a super table to model the relationships like
SuperEntity (S_Id pk)
EntityA (S_Id pk fk)
EntityB (S_Id pk fk)
GenericInfo (G_Id pk, S_id fk)
Option2: And I don't want to lose referential integrity by removing the foreign key constrain from the GenericInfo table.
EntityA (S_Id pk fk)
EntityB (S_Id pk fk)
GenericInfo (G_Id pk, unique_id non-fk)
Option3: I am currently using association tables for relationship mapping.
EntityA (A_Id pk)
EntityB (B_Id pk)
EntityAInfo(A_Id pk fk, G_Id pk fk)
EntityBInfo(B_Id pk fk, G_Id pk fk)
GenericInfo (G_Id pk)
I don't like this solution because too many tables have to be created in the database whose whole purpose is to preserve the links/relationships.
Option4: Another way I can think of is to create a mapping table with a single Id attribute like this,
EntityA (A_Id pk, I_id fk nullable)
EntityB (B_Id pk, I_id fk nullable)
InfoMapping(I_Id pk)
GenericInfo (G_Id pk, I_Id fk)
I'd love your expert opinion and input.
Thanks,
update
Vasek, thanks for your comment.
The problem I try to resolve is: How to establish object-relational mapping for an interface implementation which exposes a collection of objects?
We are using one table per class strategy for OR mapping. So each table in the example is mapped from a class. Suppose we have the following type definitions and tables (It is a pity I cannot post disgrams here)
public interface IGenericInfoProvider
{
GenericInfo [ ] GenericInfoArray {get;set;}
}
public class BaseClassForA {} --------------------------------------------- Table BaseEntityForA
public class BaseClassForB {} --------------------------------------------- Table BaseEntityForB
public class ClassA : BaseClassForA, IGenericInfoProvider {} --- Table EntityA
public class ClassB : BaseClassForB, IGenericInfoProvider {} --- Table EntityB
public class GenericInfo {} ---------------------------------------------------- Table GenericInfo
I am trying to model the one-to-many relationship between EntityA/EntityB and GenericInfo. This kind of relationships are pretty common in our domain model.
Option1 is not considered beacuse this leads to create a supertable to include all the ids from lots of tables and it doesn't make any sense in OO world.
Option2 is unacceptable because of referential integrity.
Option3 is the pattern I currently use.
I am considering Option4 but not sure if it is an approach in the right direction.
I am not sure what you wish to achieve, but I suppose it might be useful to try to use some database design tool to create the structure with tables, primary/foreign/alternate keys, compound keys, relationships etc. A picture is worth a thousand words :) and you can create various designs quickly, generate SQL code and think about how to store sample data.
For me the first scenario (Option 3) seems to represent M:N relationships. The second scenario (Option 4) represents different scenario - different referential integrity and therefore the two scenarios are not comparable.
Try to create sample databases, insert sample records and write queries.
Your current solution is the correct solution. It is the vbbest way to preserve data integrity which is the single most critical function of a database. Making more tables is something that should not even be a design consideration.