如何创建和使用泛型类EntityTypeConfiguration (How to create a

2019-09-23 15:18发布

我在我的应用程序两个非常简单的接口

表示保存在数据库实体

public interface IEntity
{
    int Id { get; set; }
}

只具有实体Nome字段必填字段保存实体

public interface IEntityName : IEntity
{
    string Nome { get; set; }
}   

而很多类实现了这个接口

public class Modalidade : IEntityName
{
    public int Id { get; set; }
    public string Nome { get; set; }
}
public class Nacionalidade : IEntityName
{
    public int Id { get; set; }
    public string Nome { get; set; }
}

public class Profissao : IEntityName
{
    public int Id { get; set; }
    public string Nome { get; set; }
}

public class TipoPessoa : IEntityName
{
    public int Id { get; set; }
    public string Nome { get; set; }
}

虽然他们相同的结构,使用完全不同的领域,例如在这个类

public class Pessoa : IEntity
{
    public int Id { get; set; }

    public string CPF { get; set; }
    public string PIS { get; set; }
    public string RG { get; set; }
    public string OrgaoExpedidor { get; set; }
    public string TipoDocumento { get; set; }
    public DateTime? DataEmissao { get; set; }

    public virtual Nacionalidade Nacionalidade { get; set; }
    public virtual Profissao Profissao { get; set; }

    public virtual TipoPessoa Tipo { get; set; }

    ....
}

问题

为了方便(而不必创建一个配置类为每个新类)创造了泛型类的配置:

internal class EntityNameConfiguracao<TEntity> : EntityTypeConfiguration<TEntity>
    where TEntity: class, IEntityName
{
    public EntityNameConfiguracao()
    {
        Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        Property(p => p.Nome).IsRequired().HasMaxLength(255);
    }
}

这样一来,我的设置,将

modelBuilder.Configurations.Add(new EntityNameConfiguracao<Modalidade>());
modelBuilder.Configurations.Add(new EntityNameConfiguracao<TipoPessoa>());
modelBuilder.Configurations.Add(new EntityNameConfiguracao<Nacionalidade>());
modelBuilder.Configurations.Add(new EntityNameConfiguracao<Profissao>());   

错误

然而,尝试添加新的迁移时,会出现以下错误:

命令

司令部设在包管理器控制台: Add-Migration PessoaDadosAdicionais

错误

The property 'Id' is not a declared property on type 'Modalidade'. Verify that the property has not been explicitly excluded from the model by using the Ignore method or NotMappedAttribute data annotation. Make sure that it is a valid primitive property.

Answer 1:

我无法解释为什么它不工作。 它只是不。 它不用于EF 4.1工作,要么。

这是特别令人惊奇,因为当你的接口转换为抽象基类的工作原理:

public abstract class BaseEntity
{
    public int Id { get; set; }
}

public abstract class BaseEntityName : BaseEntity
{
    public string Nome { get; set; }
}

public class Modalidade : BaseEntityName
{
}

然后更改通用的配置是:

internal class EntityNameConfiguracao<TEntity> : EntityTypeConfiguration<TEntity>
    where TEntity: BaseEntityName
{
    public EntityNameConfiguracao()
    {
        Property(p => p.Id)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        Property(p => p.Nome).IsRequired().HasMaxLength(255);
    }
}

现在,加入的具体构成的模型构造器不抛出异常:

modelBuilder.Configurations.Add(new EntityNameConfiguracao<Modalidade>());

(你不能添加BaseEntityBaseEntityName加入到模型,例如DbSet S表示这些类的上下文或通过提供自己的配置类,否则你会再次得到相同的例外)。

也许,抽象基类是你的选择。 否则,恐怕,你需要为每个实体创建具体的配置类摆脱异常。



文章来源: How to create and use a generic class EntityTypeConfiguration