4

Given the following model:

public class Foo
{
    public int Id { get; set;}
    public Bar TheBar { get; set; }
}

public class Bar
{
    public int Id { get; set;}
}

EF tries to generate the FK column as BarId.

How can make it use TheBar?

I've tried the following:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Foo>()
                .HasOptional(x => x.Bar)
                .WithMany()
                .IsIndependent()
                .Map(x => x.MapKey(bar => bar.Id, "TheBar"));
}

But I get the following exception when trying to use the context:

Exception has been thrown by the target of an invocation.
 ---> System.InvalidOperationException: Sequence contains more than one matching element

Server stack trace: 
   at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
   at System.Data.Entity.ModelConfiguration.Configuration.Properties.Navigation.IndependentAssociationMappingConfiguration`1.Configure(DbAssociationSetMapping associationSetMapping)
   at System.Data.Entity.ModelConfiguration.Configuration.Properties.Navigation.NavigationPropertyConfiguration.Configure(DbDatabaseMapping databaseMapping)
   at System.Data.Entity.ModelConfiguration.Utilities.IEnumerableExtensions.Each[T](IEnumerable`1 ts, Action`1 action)
   at System.Data.Entity.ModelConfiguration.Configuration.Types.EntityTypeConfiguration.ConfigureAssociationMappings(DbDatabaseMapping databaseMapping)
   at System.Data.Entity.ModelConfiguration.Configuration.Types.EntityTypeConfiguration.Configure(DbEntityTypeMapping entityTypeMapping, DbDatabaseMapping databaseMapping, DbProviderManifest providerManifest)
   at System.Data.Entity.ModelConfiguration.Configuration.ModelConfiguration.Configure(DbDatabaseMapping databaseMapping, DbProviderManifest providerManifest)
   at System.Data.Entity.ModelConfiguration.ModelBuilder.Build(DbProviderManifest providerManifest, DbProviderInfo providerInfo, Boolean validateModel)
   at System.Data.Entity.ModelConfiguration.ModelBuilder.Build(DbConnection providerConnection)
   at System.Data.Entity.Internal.LazyInternalContext.CreateModel()
   at System.Lazy`1.CreateValue()

Exception rethrown at [0]: 
   at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
   at System.Data.Entity.ModelConfiguration.Configuration.Properties.Navigation.IndependentAssociationMappingConfiguration`1.Configure(DbAssociationSetMapping associationSetMapping)
   at System.Data.Entity.ModelConfiguration.Configuration.Properties.Navigation.NavigationPropertyConfiguration.Configure(DbDatabaseMapping databaseMapping)
   at System.Data.Entity.ModelConfiguration.Utilities.IEnumerableExtensions.Each[T](IEnumerable`1 ts, Action`1 action)
   at System.Data.Entity.ModelConfiguration.Configuration.Types.EntityTypeConfiguration.ConfigureAssociationMappings(DbDatabaseMapping databaseMapping)
   at System.Data.Entity.ModelConfiguration.Configuration.Types.EntityTypeConfiguration.Configure(DbEntityTypeMapping entityTypeMapping, DbDatabaseMapping databaseMapping, DbProviderManifest providerManifest)
   at System.Data.Entity.ModelConfiguration.Configuration.ModelConfiguration.Configure(DbDatabaseMapping databaseMapping, DbProviderManifest providerManifest)
   at System.Data.Entity.ModelConfiguration.ModelBuilder.Build(DbProviderManifest providerManifest, DbProviderInfo providerInfo, Boolean validateModel)
   at System.Data.Entity.ModelConfiguration.ModelBuilder.Build(DbConnection providerConnection)
   at System.Data.Entity.Internal.LazyInternalContext.CreateModel()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
   at System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)
   at System.Data.Entity.Internal.Linq.InternalSet`1.Initialize()
   at System.Data.Entity.Internal.Linq.InternalSet`1.get_Provider()
   at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source)
   --- End of inner exception stack trace ---
   at System.RuntimeMethodHandle._InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeType typeOwner)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
Diego Mijelshon
  • 52,548
  • 16
  • 116
  • 154

2 Answers2

4

The error was caused by a bug in CTP5. If the Id property was defined in a base class (which is not shown in the code above because I didn't think it was related), it breaks.

I solved it by defining a base interface, but keeping the Id in each class.

Diego Mijelshon
  • 52,548
  • 16
  • 116
  • 154
0

You want the MapKey method in the fluent interface.

Alternately, if you do this throughout your model, CTP 5 has pluggable conventions, although this is, AFAIK, not well-documented yet.

Craig Stuntz
  • 125,891
  • 12
  • 252
  • 273
  • I have already tried with MapKey (which is awfully confusing compared to FNH or ConfORM, btw), but I get a "Sequence contains more than one matching element" exception from the bowels of EF when using the context. – Diego Mijelshon Feb 15 '11 at 21:15
  • First, that's clearly a bug in the CTP, so you should probably report it. Even if you configure incorrectly, you should get a meaningful error. Second, I've always seen `WithMany` with an expression. Have you tried that overload? – Craig Stuntz Feb 15 '11 at 21:36
  • Yes, I have, same error. Do you know where the bugtracker is? – Diego Mijelshon Feb 15 '11 at 22:06
  • 2
    The EF bug portal is [here](https://connect.microsoft.com/dataplatform/content/content.aspx?ContentID=15541) – Craig Stuntz Feb 15 '11 at 22:32
  • BTW, I think [this guy](http://stackoverflow.com/questions/4981228/entity-framework-4-ctp-5-self-referencing-many-to-many) is hitting the same bug. So it's not just you! :) – Craig Stuntz Feb 16 '11 at 18:07