未在数据库中创建具有映射的表
本文关键字:映射 创建 数据库 | 更新日期: 2023-09-27 18:31:11
我一直在尝试使用EntityFramework5实现存储库模式。我已经掌握了工作的基本知识。我的存储库仅在必要时加载,并且数据按预期在数据库中插入/更新/检索。问题是:我无法正确创建带有映射的表,甚至根本无法创建。我一直在网上阅读一些文章,甚至在这里,谈论使用映射表并在数据库中创建它们的方法,但我没有成功。在这里提出我的问题。
如何让它在我的方案中工作?
我将解释到目前为止我正在做的事情:
下面的此方法被覆盖以创建映射和表。
PS:Generics.InvokeGenericMethod
是我创建的方法,它正在起作用。它说到做到:)
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
foreach (Type entityType in Repositories.Keys)
{
//Invokes the Entity method from DbModelBuilder injecting the class type.
Generics.InvokeGenericMethod(modelBuilder, typeof(DbModelBuilder), entityType, "Entity", null);
}
foreach (GaiaEntityConfiguration config in EntityConfigurations)
{
//Defines each mapping existing in the context
config.SetConfiguration(modelBuilder);
}
}
不工作的部分是我使用SetConfiguration的地方。SetConfiguration 是我为添加到具有映射的上下文中的每个类创建的方法,并将该映射镜像到数据库。
下面是一个示例(在本例中,收件人有许多邮件,而邮件具有许多收件人/多对多关联):
PS:我留下了注释的代码,以便您可以看到我尝试的另一种方法。
public RecipientEntityConfiguration()
{
this.LeftKey = "RecipientId";
this.RightKey = "MessageId";
this.Schema = "Hermes";
this.TableName = "RecipientMessage";
}
public override void SetConfiguration(DbModelBuilder modelBuilder)
{
//EntityTypeConfiguration<Recipient> entityTypeConfiguration = new EntityTypeConfiguration<Recipient>();
//entityTypeConfiguration
// .HasMany<Message>(r => r.Messages)
// .WithMany(m => m.Recipients)
// .Map(mr =>
// {
// mr.MapLeftKey(this.LeftKey);
// mr.MapRightKey(this.RightKey);
// mr.ToTable(this.TableName, this.Schema);
// });
modelBuilder.Entity<Recipient>()
.HasMany<Message>(r => r.Messages)
.WithMany(m => m.Recipients)
.Map(mr =>
{
mr.MapLeftKey(this.LeftKey);
mr.MapRightKey(this.RightKey);
mr.ToTable(this.TableName, this.Schema);
});
//modelBuilder.Configurations.Add<Recipient>(entityTypeConfiguration);
}
调用this.Database.Initialize(false);
时,出现此错误:
Value cannot be null.
Parameter name: key
堆栈跟踪:
at System.Collections.Generic.Dictionary`2.FindEntry(TKey key)
at System.Collections.Generic.Dictionary`2.TryGetValue(TKey key, TValue& value)
at System.Data.Entity.ModelConfiguration.Configuration.Mapping.SortedEntityTypeIndex.Add(EdmEntitySet entitySet, EdmEntityType entityType)
at System.Data.Entity.ModelConfiguration.Configuration.Mapping.EntityMappingService.Analyze()
at System.Data.Entity.ModelConfiguration.Configuration.Mapping.EntityMappingService.Configure()
at System.Data.Entity.ModelConfiguration.Configuration.ModelConfiguration.ConfigureEntityTypes(DbDatabaseMapping databaseMapping, DbProviderManifest providerManifest)
at System.Data.Entity.ModelConfiguration.Configuration.ModelConfiguration.Configure(DbDatabaseMapping databaseMapping, DbProviderManifest providerManifest)
at System.Data.Entity.DbModelBuilder.Build(DbProviderManifest providerManifest, DbProviderInfo providerInfo)
at System.Data.Entity.DbModelBuilder.Build(DbConnection providerConnection)
at System.Data.Entity.Internal.LazyInternalContext.CreateModel(LazyInternalContext internalContext)
at System.Data.Entity.Internal.RetryLazy`2.GetValue(TInput input)
at System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
at System.Data.Entity.Internal.InternalContext.Initialize()
at System.Data.Entity.Database.Initialize(Boolean force)
at Gaia.Repository.GaiaContext..ctor(GaiaContextConfiguration config) in E:'Gaia'Gaia.Repository'GaiaContext.cs:line 37
at Hermes.HMail.SendMessage(Int64 sender, Int64[] toUsers, String subject, String content, FileStream attachment) in G:'Gaia'Hermes'HMail.cs:line 78
at Gaia.Controllers.ApplicationController.Test() in G:'Gaia'Gaia'Controllers'ApplicationController.cs:line 18
at lambda_method(Closure , ControllerBase , Object[] )
at System.Web.Mvc.ActionMethodDispatcher.<>c__DisplayClass1.<WrapVoidAction>b__0(ControllerBase controller, Object[] parameters)
at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
有什么想法吗?
谢谢。
首先,我在 EF Book 第 57 页中发现,任何内联配置都应仅在所有配置添加到模型构建器之后显示。检查您的代码。
接下来,尝试此版本的代码,以自动将映射添加到模型构建器。目标是从 EntityTypeConfigurations 中删除调用,并使用将配置添加到上下文的纯方法。将代码从 SetConfiguration 移动到构造函数并尝试使用我的版本。它也对我有用。
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
var entityMapTypes = assembly.GetTypes().Where(
(t => t.BaseType != null && t.BaseType.IsGenericType &&
t.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>)));
foreach (var mapType in entityMapTypes)
{
dynamic configurationInstance = Activator.CreateInstance(mapType);
modelBuilder.Configurations.Add(configurationInstance);
}
}
这将是我在stackoverflow中的第一个答案,所以我希望它对某人有所帮助!事实证明,EF 是一种敏感的生物,它不喜欢具有名为"Type"的属性的实体,因此如果您有任何实体,只需将它们重命名为"EntityType"之类的名称即可。
我也听说过人们对具有抽象类型的属性有类似的问题,以防万一某人的问题不是我上面描述的问题,请查看您的属性类型并检查它们是否抽象:数据库上下文初始化模型优先数据库失败