I've been trying to implement the Repository pattern using EntityFramework5. I already got the basics to work. My repositories are being loaded only when necessary and the data is being inserted/updated/retrieved in the database as it should. The problem is: I can't get the tables with mapping to be correctly created, or even created at all. I've been reading some articles online, even here, talking about ways to work with mapped tables and create them in the database, but I haven't succeed. Hands my question here.
How do I get it to work in my scenario?
I'll explain what I'm doing so far:
This method below is overriden to, supposedly, create the mappings and tables.
PS: Generics.InvokeGenericMethod
is a method I created and it's working. It does what it says :)
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);
}
}
The part that is not working is where I use SetConfiguration. SetConfiguration is a method I created for each class added to the context that has mapping, have that mapping mirrored to the database.
Here's one example (in this case a recipient has many messages and messages have many recipients / many-to-many association):
PS: I left the commented code so you can see one other approach I tried.
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);
}
When this.Database.Initialize(false);
is called I get this error:
Value cannot be null.
Parameter name: key
StackTrace:
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)
Any ideas?
Thanks.