2016-09-30 2 views
0

Я моделирую новую базу данных EF CodeFirst. Здесь у меня есть абстрактный базовый класс и все модели предметной области, унаследованные от этого класса:Entity Framework: можно ли наследовать из базового класса конфигурации?

public abstract class Entity 
{ 
    public Guid Id { get; set; } 
    public byte [] TimeStamp { get; set; } 
} 

И там много классов, как:

public class Country : Entity 
{ 
    public string Name { get; set; } 
    public string InternationalCode { get; set; } 
    public Location Location { get; set; } 
    public ICollection<City> Cities { get; set; } 

    public Country(string name, string internationalCode, decimal latitude, decimal longitude) 
     : this(name, internationalCode) 
    { 
     Location.Latitude = latitude; 
     Location.Longitude = longitude; 
    } 
    public Country(string name, string internationalCode) : this() 
    { 
     Name = name; 
     InternationalCode = internationalCode; 
    } 

    public Country() 
    { 
     Location = new Location(); 
     Cities = new List<City>(); 
    } 
} 

и конфигурация каждой модели на основе FluentAPI:

public CountryConfiguration() 
    { 
     HasKey(p => p.Id); 
     Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 
     Property(p => p.TimeStamp).IsRowVersion(); 

     Property(p => p.Name).IsRequired().HasMaxLength(100); 
     Property(p => p.InternationalCode).IsRequired().HasMaxLength(5); 

     HasMany(p => p.Cities) 
      .WithOptional(p => p.BelongedCountry) 
      .HasForeignKey(p => p.BelongedCountryId); 
    } 

проблема заключается в том, что

 HasKey(p => p.Id); 
     Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 
     Property(p => p.TimeStamp).IsRowVersion(); 

этот кусок скопирован более чем в 30 раз для каждой модели домена. Есть ли способ сделать классы конфигурации наследовать от EntityTypeConfiguration, но также наследовать \ содержать конфигурацию из конфигурации Entity?

public class EntityConfiguration : EntityTypeConfiguration<Entity> 
{ 
    public EntityConfiguration() 
    { 
     HasKey(p => p.Id); 
     Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 
     Property(p => p.TimeStamp).IsRowVersion(); 
    } 
} 

Я знаю, что C# не допускает множественного наследования. Что вы можете предложить?

ответ

3

Если мне что-то не хватает, не можете ли вы использовать абстрактный класс?

public abstract class BaseEntityConfiguration<T> : EntityTypeConfiguration<T> where T : Entity 
{ 
    protected BaseEntityConfiguration() 
    { 
     HasKey(p => p.Id); 
     Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 
     Property(p => p.TimeStamp).IsRowVersion(); 
    } 
} 

public class CountryConfiguration : BaseEntityConfiguration<Country> 
{} 
1

Просто глядя на ваших фрагментах, и как я мог бы структурировать, чтобы удовлетворить ваши требования, я мог бы изменить свой класс EntityConfiguration так:

public class EntityConfiguration<TEntityType> : EntityTypeConfiguration<TEntityType> where TEntityType : Entity 
{ 
    public EntityConfiguration() 
    { 
    HasKey(p => p.Id); 
    Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 
    Property(p => p.TimeStamp).IsRowVersion(); 
    } 
} 

Затем вы можете создать наследственные конфигурации, как ваш CountryConfiguration:

public class CountryConfiguration : EntityConfiguration<Country> 
{ 
    public CountryConfiguration() : base() 
    { 
    Property(p => p.Name).IsRequired().HasMaxLength(100); 
    Property(p => p.InternationalCode).IsRequired().HasMaxLength(5); 
    } 
} 

ограничивая общего типа на классе EntityConfiguration с ИНЕКЕ базового типа Entity, вы будете иметь возможность работать с го ose в классе EntityConfiguration, оставив остальное на производные классы для ваших конкретных моделей.

0

Я ценю решения, предоставляемые @mxmissile и @Jodacola, вы сделали именно то, что я искал.

Я просто хочу добавить, что я нашел еще один «ошибка» способ сделать то, что я спросил:

modelBuilder.Entity<Entity>().HasKey(p => p.Id); 
     modelBuilder.Entity<Entity>().Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 
     modelBuilder.Entity<Entity>().Property(p => p.TimeStamp).IsRowVersion(); 

     modelBuilder.Configurations.Add(new CountryConfiguration()); 
     modelBuilder.Configurations.Add(new CityConfiguration()); 
     modelBuilder.Configurations.Add(new LocationConfiguration()); 
     modelBuilder.ComplexType<Location>(); 

Это «не подходит» решение, и я просто опубликовать его в академических целях. По некоторым причинам он создал таблицу «Объекты» в базе данных. Я был бы очень благодарен, если бы вы могли объяснить, почему здесь создана таблица «Entities» в db?

В db он содержит копию всех идентификаторов всех объектов, унаследованных от класса Entity.

+0

Вы должны задать новый вопрос. Но вам не нужны первые три строки этого кода. Поскольку ваши классы конфигурации наследуются от базового конфигурационного класса. – mxmissile

+0

@mxmile, нет, здесь я использую «обычные» классы конфигурации без наследования. Я последую за советом и задаю другой вопрос. –

Смежные вопросы