Search code examples
c#mysqlentity-frameworkforeign-keys

EntityFramework: 1:0..1 relation deserialized as collection


I have a problem with entityframework which serializes a 1:0..1 relation between two tables as a collection.

I have 2 tables on my Database:

CREATE TABLE `revisiones` (
  `Id` int(11) NOT NULL AUTO_INCREMENT,
  ---Irrelevant columns here---
  PRIMARY KEY (`Id`),
  ---Irrelevant constraint and foreign keys here---
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

CREATE TABLE `ficha_deposito` (
  `Id` int(11) NOT NULL AUTO_INCREMENT,
  `IdRevision` int(11) NOT NULL,
  ---Irrelevant Columns Here---
  PRIMARY KEY (`Id`),
  UNIQUE KEY `IdRevision_UNIQUE` (`IdRevision`),
  CONSTRAINT `fk_ficdep_rev` FOREIGN KEY (`IdRevision`) REFERENCES `revisiones` (`Id`) ON DELETE CASCADE ON UPDATE CASCADE,
  ---Irrelevant constraints here---
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

As you can see a revision may be related as none or 1 ficha_deposito, due the unique restriction.

However on the edmx file, the relation is serialized as a collection:

enter image description here

If I try to change it manually (I would prefer to not do so, because if I have to regenerate the model, I will have to set the value again manually), then I get an exception:

Running transformation: Multiplicity is not valid in Role 'ficha_deposito' in relationship 'fk_ficdep_rev'. Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be *.

Why can't I change the multiplicity of the relation? revision.ficha_deposito should be null or a simple object.


Solution

  • This is a EF6 limitation. EF naturally supports one-to-one relationship via so called Shared Primary Key Associations, where there is no separate FK in the dependent entity, but the PK is also used as FK to the principal table.

    When the dependent entity is using a separate FK field, even if it's backed with an unique constraint, from EF perspective it's still one-to-many relationship. I can't explain it better than in the One-to-One Foreign Key Associations:

    As you may have noticed, both associations in the fluent API code has been configured as a many-to-one — not one-to-one, as you might have expected. The reason is simple: Code First (and EF in general) does not natively support one-to-one foreign key associations. In fact, EF does not support any association scenario that involves unique constraints at all.

    and then

    The second limitation that this lack of support impose to us is more important: one to one foreign key associations cannot be bidirectional (e.g. we cannot define a property for the User on the Address class).

    The good news are that such support has been added to EF Core, so when it becomes usable (v1.1 or later) you'll be able to set up such relationship. Until then, you should live with one-to-many.