【问题标题】:How to create and use a generic class EntityTypeConfiguration<TEntity>如何创建和使用泛型类 EntityTypeConfiguration<TEntity>
【发布时间】:2012-10-06 18:05:15
【问题描述】:

代码

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

表示保存在数据库中的实体

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.

【问题讨论】:

    标签: ef-code-first entity-framework-5 entity-framework-migrations


    【解决方案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 添加到模型中,例如将这些类的DbSets 添加到上下文中或提供它们自己的配置类,否则您将再次遇到相同的异常.)

    也许,抽象基类是您的替代品。否则,恐怕您需要为每个实体创建具体的配置类才能摆脱异常。

    【讨论】:

      猜你喜欢
      • 2021-05-05
      • 2021-03-30
      • 2022-10-15
      • 2021-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-10
      相关资源
      最近更新 更多