0

我一直在尝试使用 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)

有任何想法吗?

谢谢。

4

2 回答 2

2

首先,我在EF Book pg.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);
     }
} 
于 2012-11-05T18:53:02.737 回答
1

这将是我在stackoverflow中的第一个答案,所以我希望它对某人有所帮助!事实证明 EF 是一个敏感的生物,它不喜欢具有名为“Type”的属性的实体,所以如果你有的话,只需将它们重命名为类似于“EntityType”的东西。

我还听说有人对具有抽象类型的属性有类似的问题,以防万一有人的问题不是我上面描述的问题,请查看您的属性的类型并检查它们是否是抽象的: DbContext 无法初始化模型优先数据库

于 2012-09-14T12:38:29.507 回答