views:

395

answers:

4

I have to 2 entities like this:

class A
{
   int id { get; set; }
   string Name { get; set; }
}

class B
{
   int id { get; set; }
   A RefToA { get; set; }
   string Name { get; set; }
}

How can I map this 2 classes so that i would have 3 tables like this:

  • table A with 2 columns: id and name

  • table B with 2 columns: id and name

  • table AB with 2 columns: AId and BId

+1  A: 

This is a typical ManyToMany relationship. In FluentNHibernate you would use

HasManyToMany<T>();

http://wiki.fluentnhibernate.org/Fluent_mapping#HasManyToMany_.2F_many-to-many

statichippo
I know that I can do this as a simple ManyToMany relationship, but this will require me to put a list in my entity instead of a simple reference
Omu
+1  A: 

what you want is References(x => x.RefToA);

The following below is from the fluent nhibernate documenation.

References / many-to-one

References is for creating many-to-one relationships between two entities; you're referencing another entity, so you use the References method. A reference is to a single instance of an entity

http://wiki.fluentnhibernate.org/Fluent_mapping

Mike Geise
yes but this will create a FK id Column, and I don't want that, I need a 3rd table instead
Omu
Then what you want is HasOne(x => x.RefToA);any reason you don't want a PK for the thrid table? legacy?
Mike Geise
I don't need another FK column in my table because most of the time this column is going to be null, so that's why I want to put it into a 3rd table, I could have done it with HasManyToMany but with this approach I would have had to write MyCollectionProperty[0] all the time (because it can be no more than one)
Omu
+2  A: 

If I understand this correct you are creating a ref table because you want the reference to be nullable. If that is the case, you do not need a ref table. Simply set the FK in table b as nullable. Then you can map it a simple reference. Then you would have tables like this:

  • table A with 2 columns: id and name
  • table B with 2 columns: id, name and Aid (nullable)

And you can map it like this:

public class AMap : ClassMap<A>
{
  public AMap()
  {
      Id(x => x.Id); 
      Map(x => x.Name);
  }
}

public class BMap : ClassMap<B>
{
  public BMap()
  {
     Id(x => x.Id); 
     Map(x => x.Name);
     References(x => x.RefToA);
  }
}

Update

There is no way of mapping this how you want in nhibernate (and no other orm for that matter). The reason for this is quite simple: it violates quite a few rules and there is never a reason to do it this way. The correct way to do this is to have a nullable fk reference in table b. That is how you represent a reference in a sql database. It is simply bad design to use many-to-many when you mean one-to-many and it will most certainly give you trouble later on.

Mattias Jakobsson
it's not because it is nullable, it's because i don't want it to be present in that table
Omu
I can't see why? What would that gain you?
Mattias Jakobsson
I'm not going to have a FK column in my table that is almost always going to be null
Omu
What is wrong with References(x => x.RefToA).CanBeNull(); This is probably the only way you are going to get close to what you want with fluent nhibernate. I think it might be time for a redesign.
Mike Geise
In my opinion you should rethink that a little bit. There is no way to map a many-to-many as a one-to-many in nhibernate (neither should there). It would do you no harm in having that extra field in that table. But if you would have it as a ref table you would always have a join.
Mattias Jakobsson
I kinda agree with you, my team leader wants it that way, he said it has something to do with Boyce-Code normal form, that says that there should be no null values or references or something
Omu
I would strongly argue against him on this one. The way he suggest breaks a lot more patterns and rules then having a nullable FK. What would happen if one B has references to two different A's? You can work against this in your application. But that forces the application to handle data integrity. That is a job for the database.
Mattias Jakobsson
A: 

You should not be mapping a one-to-many relation as a many-to-many relation, then forcing it to be a one-to-many. Its bad design, and does not promote data integrity. If I were you, I would create your tables as follows

CREATE TABLE A(
    Id INT PRIMARY KEY IDENTITY(1,1),
    --Your other columns
)

CREATE TABLE B(
    Id INT PRIMARY KEY IDENTITY(1,1),
    AId INT REFERENCES A NULL,
    --Your other columns
)

That way, you can map them the way you want to in Fluent NHibernate, or any other ORM.

phsr