Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC Scaffolding and EF 'One To Zero or One' relationships error

In my AspNet MVC 3 project when I try to scaffold an entity which has a One to Zero or One relationship with another entity I get "An item with the same index has already been added" error.

Essentially this happens when the Primary Key of the related table is also a Foreign Key.

At the moment my workaround is

  1. Add an Id column to the related table and make it the primary key

  2. Add Unique Key to the Foreign Key Column.

The problem with this is that EF will generate an ICollection navigation property for the related entity instead of just a property of the related entity type (which I can set to null in case of zero related entities)

Is this a know bug?

Am I doing something wrong?

Is there a better work around to get rid of the ICollection navigation property?

like image 459
NVM Avatar asked Feb 15 '12 10:02

NVM


1 Answers

See my answer on this question:

How do I code an optional one-to-one relationship in EF 4.1 code first with lazy loading and the same primary key on both tables?

That's the example code with the correct configuration.

public class ZoneMedia
{
    public int ZoneMediaID { get; set; }
    public string MediaName { get; set; }
    public int Width { get; set; }
    public int Height { get; set; }

    public virtual ZoneMediaText MediaText { get; set; }
}

public class ZoneMediaText
{
    public int ZoneMediaID { get; set; }
    public string Text { get; set; }
    public int Color { get; set; }

    public virtual ZoneMedia ZoneMedia { get; set; }
}

public class TestEFDbContext : DbContext
{
    public DbSet<ZoneMedia> ZoneMedia { get; set; }
    public DbSet<ZoneMediaText> ZoneMediaText { get; set; }

    protected override void OnModelCreating (DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<ZoneMedia>()
            .HasOptional(zm => zm.MediaText);
        modelBuilder.Entity<ZoneMediaText>()
            .HasKey(zmt => zmt.ZoneMediaID);
        modelBuilder.Entity<ZoneMediaText>()
            .HasRequired(zmt => zmt.ZoneMedia)
            .WithRequiredDependent(zm => zm.MediaText);

        base.OnModelCreating(modelBuilder);
    }
}
class Program
{
    static void Main (string[] args)
    {
        var dbcontext = new TestEFDbContext();
        var medias = dbcontext.ZoneMedia.ToList();
    }
}

You can also achieve this with DataAnnotations, but I generally prefer to keep my entity models as POCOs.

like image 193
WDRust Avatar answered Sep 21 '22 19:09

WDRust