9

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?

Mike
  • 1,992
  • 4
  • 31
  • 42
NVM
  • 5,442
  • 4
  • 41
  • 61
  • Are you using DbContext code generation? – Danny G Feb 22 '12 at 19:58
  • I'm using DbContext in EF 4.3 and have the same problem. My app uses Code First to generate the DB. It seems, that in < EF 4.3 it was possible to create to tables with the same Primary Key (e.g. in my DB, the table customer and employee both has a PK called PublicKey which must be unique....but it no longer works) – Mike Feb 23 '12 at 01:43
  • You should use foreign key of related table as primary key too - it's only way to implement 1-(0,1) relationship. – David Levin Feb 24 '12 at 08:24
  • @Danny Yes Using DbContext code generation. – NVM Feb 24 '12 at 08:34

2 Answers2

3

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.

Community
  • 1
  • 1
WDRust
  • 3,663
  • 1
  • 19
  • 23
1

Try to use the [Key] attribute to the intended primary key. You may need to import the namespace System.ComponentModel.DataAnnotations

Also check the documentation about the full implementation of this namespace.

http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.aspx

Danny G
  • 3,660
  • 4
  • 38
  • 50