Look at this page for more details.
Basically a one to one relationship is that in which the PK of the principal entity passes as PK and FK in the dependent entity. As far I can see here you need to map two entities as optional between each other and that's not really possible in EF, at least not as One to Zero-Or-One.
I understand that you want both sides to be optional but turns out that EF needs to know which one of your entities is the principal. So here is a way to change the relationships. I'd suggest you to define your principal entity in the relationship and the other become optional. E.g:
User as the principal:
//Your entities
public class Image
{
public Guid UserId { get; set; }
public virtual User User { get; set; }
}
public class User
{
public Guid UserId { get; set; }
public virtual Image Image { get; set; }
}
//Mappings:
public class ImageMappingConfiguration : EntityTypeConfiguration<Image>
{
public ImageMappingConfiguration()
{
HasKey(x => x.UserId);
}
}
public class UserMappingConfiguration : EntityTypeConfiguration<User>
{
public UserMappingConfiguration()
{
HasKey(x => x.UserId);
HasOptional(x => x.Image)
.WithRequired(x => x.User);
}
}
You'll get this after add-migration:
public override void Up()
{
CreateTable(
"dbo.Images",
c => new
{
UserId = c.Guid(nullable: false)
})
.PrimaryKey(t => t.UserId)
.ForeignKey("dbo.Users", t => t.UserId)
.Index(t => t.UserId);
CreateTable(
"dbo.Users",
c => new
{
UserId = c.Guid(nullable: false)
})
.PrimaryKey(t => t.UserId);
}
See the primary key of User passing as PK and FK to Image? That's the way EF handles One to Zero-Or-One relations.

UPDATE! Two One-To-Many relationships with Unique Constraints.
Let's give a try to this approach. Let me know if this works for you.
public sealed class Image
{
public Image()
{
Users = new List<User>();
}
public Guid Id { get; set; }
public Guid? UserId { get; set; }
public List<User> Users { get; set; }
public User User { get; set; }
}
public sealed class User
{
public User()
{
Images = new List<Image>();
}
public Guid Id { get; set; }
public Guid? ImageId { get; set; }
public List<Image> Images { get; set; }
public Image Image { get; set; }
}
//Mappings:
public class ImageMappingConfiguration : EntityTypeConfiguration<Image>
{
public ImageMappingConfiguration()
{
HasKey(x => x.Id);
Property(x => x.UserId)
.HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute("IX_ImageMustBeUnique")
{
IsUnique = true
}));
HasMany(x => x.Users)
.WithOptional(x => x.Image)
.HasForeignKey(x => x.ImageId)
.WillCascadeOnDelete(true);
}
}
public class UserMappingConfiguration : EntityTypeConfiguration<User>
{
public UserMappingConfiguration()
{
HasKey(x => x.Id);
Property(x => x.ImageId)
.HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute("IX_UserMustBeUnique")
{
IsUnique = true
}));
HasMany(x => x.Images)
.WithOptional(x => x.User)
.HasForeignKey(x => x.UserId);
}
}
Usage:
//test adding a user and an image.
var user = new User
{
Id = Guid.NewGuid(),
};
var image = new Image
{
Id = Guid.NewGuid(),
};
using (var ctx = new Context())
{
ctx.Users.Add(user);
ctx.Images.Add(image);
ctx.SaveChanges();
//associate them
user.Images.Add(image);
image.Users.Add(user);
ctx.SaveChanges();
//try to add a second image to the user
var image2 = new Image
{
Id = Guid.NewGuid()
};
try
{
user.Images.Add(image2);
ctx.SaveChanges();
}
catch (DbUpdateException ex)
{
Console.WriteLine(ex);
}
}