I am working in asp.net core project using EF core. I mapped my entities by overriding the OnModelCreating function in the context class. I can easily map these entities manually. Well, I would better post my codes and explain ..
This is what I did in my Context class:
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
//builder.RegisterEntityMapping<CodeTable, CodeTableMap>();
builder.RegisterEntityMapping<Country, CountryMap>();
builder.RegisterEntityMapping<State, StateMap>();
builder.RegisterEntityMapping<City, CityMap>();
builder.RegisterEntityMapping<User, UserMap>();
builder.RegisterEntityMapping<Prospect, ProspectMap>();
}
Country.cs
public class Country:BaseEntity
{
public string CountryCode { get; set; }
public string CountryName { get; set; }
public string Currency { get; set; }
public string CurrencyName { get; set; }
public string UnitOfMeasure { get; set; }
public string TelephoneCountryCode { get; set; }
public string CurrencySymbol { get; set; }
public virtual ICollection<State> States { get; set; }
public virtual ICollection<City> Cities { get; set; }
}
CountryMap.cs
public class CountryMap : QuantumEntityTypeConfiguration<Core.Domain.Country>
{
public override void Map(EntityTypeBuilder<Core.Domain.Country> builder)
{
builder.ToTable("Country");
builder.HasKey(pr => pr.CountryCode);
builder.HasMany(m => m.Cities).WithOne(i=> i.Country).HasForeignKey(m=> m.CountryCode);
builder.HasMany(m => m.States).WithOne(i => i.Country).HasForeignKey(m => m.CountryCode);
}
}
But, I would like to do it dynamically as it would be hectic later on to map all the models. I could find the solution in nopCommerce's context class where they did in this way:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//dynamically load all configuration
//System.Type configType = typeof(LanguageMap); //any of your configuration classes here
//var typesToRegister = Assembly.GetAssembly(configType).GetTypes()
var typesToRegister = Assembly.GetExecutingAssembly().GetTypes()
.Where(type => !String.IsNullOrEmpty(type.Namespace))
.Where(type => type.BaseType != null && type.BaseType.IsGenericType &&
type.BaseType.GetGenericTypeDefinition() == typeof(NopEntityTypeConfiguration<>));
foreach (var type in typesToRegister)
{
dynamic configurationInstance = Activator.CreateInstance(type);
modelBuilder.Configurations.Add(configurationInstance);
}
//...or do it manually below. For example,
//modelBuilder.Configurations.Add(new LanguageMap());
base.OnModelCreating(modelBuilder);
}
I tried to implement that and I got an error:
protected override void OnModelCreating(ModelBuilder builder)
{
// TODO: Use Dynamic mapping by getting classes which uses QuantumEntityTypeConfiguration
var typesToRegister = Assembly.GetExecutingAssembly().GetTypes()
.Where(type => !String.IsNullOrEmpty(type.Namespace))
.Where(type => type.BaseType != null && type.BaseType.IsGenericType &&
type.BaseType.GetGenericTypeDefinition() == typeof(QuantumEntityTypeConfiguration<>));
foreach (var type in typesToRegister)
{
dynamic configurationInstance = Activator.CreateInstance(type);
builder.Configurations.Add(configurationInstance); //Error in this line specifying:ModelBuilder has no defination for Configuration.
}}
Well nopCommerce uses the DbModelBuilder from namespace: System.Data.Entity and I use ModelBuilder under namespace : Microsoft.EntityFrameworkCore.
So, if you have any solutions or recommendations. please let me know.
In EF Core, there is no Configurations
property available on ModeBuilder
as of now.
One way to work around this issue is to change your configurations to
public class CountryMap : QuantumEntityTypeConfiguration<Country>
{
public CountryMap(ModelBuilder modelBuilder)
{
EntityTypeBuilder<Country> builder = modelBuilder.Entity<Country>()
builder.ToTable("Country");
builder.HasKey(pr => pr.CountryCode);
builder.HasMany(m => m.Cities).WithOne(i=> i.Country).HasForeignKey(m=> m.CountryCode);
builder.HasMany(m => m.States).WithOne(i => i.Country).HasForeignKey(m => m.CountryCode);
}
}
And then you can add them in your DbContext's on OnModelCreating
method like this:
foreach (var type in typesToRegister)
{
Activator.CreateInstance(type, modelBuilder);
}