实体框架:是否可以从基本配置类继承?

时间:2016-09-30 20:10:30

标签: c# entity-framework

我正在通过EF CodeFirst为新数据库建模。这里我有一个抽象基类和从这个类继承的每个域模型:

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 ,还可以继承\ contains实体配置?

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 个答案:

答案 0 :(得分:4)

除非我遗漏了什么,否则你不能使用抽象类吗?

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 :(得分:2)

只需查看您的代码段,以及如何构建它以满足您的要求,我可能会改变您的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);
  }
}

通过使用where子句将EntityConfiguration类的泛型类型限制为基本实体类型,您将能够在EntityConfiguration类中使用这些基本属性,而将其余属性保留到特定模型的派生类中

答案 2 :(得分:1)

我很欣赏@mxmissile和@Jodacola提供的解决方案,你正是我所寻找的。

我只想补充一点,我发现了另一个&#34; bug&#34;做我问的方式:

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>();

这是不合适的&#34;解决方案,我只是出于学术目的。 由于某些原因,它创建了一个表&#34;实体&#34;在数据库中。如果你能解释一下,我会非常感激,为什么在这里创建一个表&#34;实体&#34;在db?

在db中,它包含从Entity类继承的所有实体的所有Id的副本。