1

I have a repro for what I think might be an EF bug. I would like to split one table across two entities. Each of those entites contains a reference to a third entity. The two references must be exposed with identical foreign key property names. Since they map to columns in the same table, configuration (or, in this example, an attribute) is used to make the column names unique.

When I try to load the model, I get the above exception from EF. If I modify the name of one of the FK properties then the error goes away.

Here is my model. The code as-is works. To reproduce the problem, rename Foo2.Foo3Id1 to Foo3Id, which is the value that I need it to have.

Why Would You Want to Do That?

If you're wondering why I need the two properties to have the same name, here's the explanation.

I have a table that contains several addresses (e.g. a postal address and a billing address). This is an existing database, so I can't change the table structure. Each address is represented by a series of standard columns. The name of each column has a prefix identifying the kind of address and a suffix identifying the part of the address, e.g. BillingAddressLine1, BillingAddressZipCode and PostalAddressLine1.

It would seem that using a complex type would handle this. However, there is an added complication: each address contains a CityId that references a Cities table. Complex types don't support relationships and navigation properties. So my intended solution is to use table splitting instead, and to split each set of address properties into its own entity. Each entity that represents an address either derives from a base type, say, Address or implements an interface, IAddress.

With table splitting I'm careful to observe the restriction that where several types are mapped to the same table, they must all have navigation properties to each other.

In the code below, Foo1 and Foo2 are both address types (and would implement some common interface). Foo3 is City. This is the simplest repro of the problem that I could come up with.

Code Sample

class Program
{
    static void Main(string[] args)
    {
        // Use NuGet to import EF 5 into the project.
        // This code is just enough to cause the metadata to be loaded and therefore demo the error.
        using (Context cx = new Context())
        {
            var qq = from f in cx.Foo3s
                     where f.Foo1s.Any()
                     select f;
        }
    }
}

[Table("Foo")]
public class Foo1
{
    [Key]
    public virtual int Id { get; set; }

    [Required]
    public virtual Foo2 Foo2 { get; set; }

    [ForeignKey("Foo3")]
    [Column("Foo1_Foo3Id")]
    public virtual int? Foo3Id { get; set; }

    public virtual Foo3 Foo3 { get; set; }
}

[Table("Foo")]
public class Foo2
{
    [Key]
    public virtual int Id { get; set; }

    [Required]
    public virtual Foo1 Foo1 { get; set; }

    // Re-name the following property to Foo3Id (rather than Foo3Id1) and the model won't load.
    // You get "InvalidOperationException: Sequence contains more than one matching element."
    [ForeignKey("Foo3")]
    [Column("Foo2_Foo3Id")]
    public virtual int? Foo3Id1 { get; set; }

    public virtual Foo3 Foo3 { get; set; }
}

[Table("Foo3")]
public class Foo3
{
    [Key]
    public virtual int Id { get; set; }

    [InverseProperty("Foo3")]
    public virtual ICollection<Foo1> Foo1s { get; set; }

    [InverseProperty("Foo3")]
    public virtual ICollection<Foo2> Foo2s { get; set; }
}

public class Context : DbContext
{
    public DbSet<Foo3> Foo3s { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        // Don't think we can configure 1:1 relationship using just attributes.
        var foo2 = modelBuilder.Entity<Foo2>();
        foo2.HasRequired(q => q.Foo1)
            .WithRequiredPrincipal(q => q.Foo2);
    }
}

Is this a bug? Am I doing something wrong? Is it a known EF limitation?

Community
  • 1
  • 1
Olly
  • 5,966
  • 31
  • 60
  • Can you report this on http://entityframework.codeplex.com? I don't know if this is supported but if it is not then you should get a better exception – Pawel Nov 04 '12 at 02:56
  • @Pawel - Thanks. I've created http://entityframework.codeplex.com/workitem/643 and added some more info here on why I'm trying to do this. It sounds a bit obscure without that background info. – Olly Nov 05 '12 at 14:36
  • Brice found a workaround you could use until it's fixed - he posted it on the codeplex site. Just in case: "Changing one of the property names is a valid workaround until this gets fixed." – Pawel Nov 07 '12 at 04:44
  • @Pawel - Thanks, though I did explain that in my scenario, "The two references *must* be exposed with identical foreign key property names." It looks as though I just can't do what I want to do right now. – Olly Nov 07 '12 at 13:10

2 Answers2

1

This was indeed a bug, and it has now been fixed. See http://entityframework.codeplex.com/workitem/643.

Olly
  • 5,966
  • 31
  • 60
  • that was in 6.0.0. My link was about 6.1.0 which maybe reintroduced it. but it seems fixed now (?) – juFo Apr 27 '14 at 09:57
1

The bug was still around in 6.0. Have a look here: https://entityframework.codeplex.com/workitem/546 + another related bug: https://entityframework.codeplex.com/workitem/2116

juFo
  • 17,849
  • 10
  • 105
  • 142