EF Code First CTP5 - 使用属性名称作为外键的列名

Posted

技术标签:

【中文标题】EF Code First CTP5 - 使用属性名称作为外键的列名【英文标题】:EF Code First CTP5 - Using the name of the property as column name for foreign key 【发布时间】:2011-02-15 19:21:55 【问题描述】:

给定以下模型:

public class Foo

    public int Id  get; set;
    public Bar TheBar  get; set; 


public class Bar

    public int Id  get; set;

EF 尝试将 FK 列生成为 BarId

如何让它使用TheBar

我尝试了以下方法:

protected override void OnModelCreating(ModelBuilder modelBuilder)

    modelBuilder.Entity<Foo>()
                .HasOptional(x => x.Bar)
                .WithMany()
                .IsIndependent()
                .Map(x => x.MapKey(bar => bar.Id, "TheBar"));

但在尝试使用上下文时出现以下异常:

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)

【问题讨论】:

【参考方案1】:

该错误是由 CTP5 中的错误引起的。如果 Id 属性是在基类中定义的(上面的代码中没有显示,因为我认为它不相关),它会中断。

我通过定义一个基接口解决了这个问题,但在每个类中保留了 Id。

【讨论】:

感谢 Diego 的分享,我也遇到了完全相同的问题。【参考方案2】:

您希望fluent interface 中的MapKey 方法。

或者,如果您在整个模型中执行此操作,CTP 5 具有可插入的约定,尽管这在 AFAIK 中还没有很好的文档记录。

【讨论】:

我已经尝试过使用 MapKey(与 FNH 或 ConfORM 相比,这非常令人困惑,顺便说一句),但是在使用上下文。 首先,这显然是 CTP 中的一个错误,因此您应该报告它。即使您配置不正确,您也应该得到一个有意义的错误。其次,我总是看到WithMany 有一个表情。你试过超载吗? 是的,我有,同样的错误。你知道 bugtracker 在哪里吗? EF 错误门户是here 顺便说一句,我认为this guy 遇到了同样的错误。所以不只是你! :)

以上是关于EF Code First CTP5 - 使用属性名称作为外键的列名的主要内容,如果未能解决你的问题,请参考以下文章

使用 EF4 Code First 时如何控制生成的 nvarchar 列的长度?

EF4 Code only ctp5:如何设置连接字符串 devart oracle?

实体框架 CTP5,代码优先。可选的导航属性

首先关闭 EF 代码的 CTP5 的 ProxyCreationEnabled 有啥缺点

EF4 CTP5 POCO 中的软删除、导航属性

在使用 EF 4.1 Code-First 的 Include 和/或 Select 方法时订购导航属性?