Entity Framework Code First - Vantagens e desvantagens de Fluent Api vs Data Annotations [fechado]

120

Ao criar um banco de dados usando primeiro o código do Entity Framework, muito do modelo de banco de dados pode ser extraído do código. API e / ou atributos fluentes podem ser usados ​​para ajustar o modelo.

Quais são as vantagens e desvantagens do Fluent Api em comparação com as anotações de dados? Em outras palavras: mesmo que em certas situações ambos os métodos possam ser usados, em que casos um método deve prevalecer sobre o outro?

Sam
fonte
3
Apenas uma ideia: o que eu normalmente faço é criar um projeto de modelo com meus POCOs e, em seguida, no projeto de repositório, criar um novo conjunto de POCOs especificamente para EF e colocar minhas anotações lá. Então, eu apenas mapeio entre os dois nas classes mapeadoras. Dessa forma, meu modelo permanece intocado e torna mais fácil adicionar / alterar minha estratégia de dados, se necessário (por exemplo, adicionar um XmlRepository e usar as mesmas classes de modelo).
adimauro
1
Agora prefiro Annotation, com EFCore e bibliotecas adicionais. (requer menos código, e tudo está em um só lugar) github.com/isukces/EfCore.Shaman - adiciona e estende atributos github.com/borisdj/EFCore.FluentApiToAnnotation - útil quando o banco de dados já existe, após fazer engenharia reversa e mudar para CodeFirst
borisdj

Respostas:

141

Tudo o que você pode configurar com DataAnnotations também é possível com a API Fluent. O contrário não é verdade. Portanto, do ponto de vista das opções de configuração e flexibilidade, a API Fluent é "melhor".

Exemplos de configuração (com certeza, não uma lista completa) que são possíveis na API Fluent, mas não com DataAnnotations (pelo que posso ver):

  • Desative as exclusões em cascata:

    .WillCascadeOnDelete(false)

  • Especifique o nome da coluna da chave estrangeira no banco de dados quando a chave não estiver exposta em seu modelo de objeto:

    .Map(conf => conf.MapKey("MyForeignKeyID"))

  • Ajuste granular de relacionamentos, especialmente em todos os casos em que apenas um lado de uma associação é exposto no modelo de objeto:

    .WithMany(...), WithOptional(...), WithRequiredDependent(...),WithRequiredPrincipal(...)

  • Especificação do mapeamento de herança entre o modelo de objeto e as tabelas do banco de dados (Tabela por Hierarquia, Tabela por Tipo, Tabela Por Classe Concreta):

    .Map<TDerived>(Action<EntityMappingConfiguration<TDerived>> ...)

Editar: a Microsoft considera a API Fluent como um "recurso avançado" (cite aqui ):

A API fluente é considerada um recurso mais avançado e recomendamos o uso de anotações de dados, a menos que seus requisitos exijam o uso da API fluente.

Mas, em minha opinião, você atinge as limitações de DataAnnotations muito rapidamente (exceto, talvez, para modelos de objeto extremamente simples). Se você não puder mais ajustar seu modelo com DataAnnotations, seu último recurso é seguir as convenções de mapeamento padrão (nomeando suas propriedades de acordo com essas regras). Atualmente você não pode sobrescrever as convenções (apenas desabilitá-las; a MS anunciou para dar opções de configuração para as convenções em versões futuras do EF). Mas se você não quiser ser forçado pelas convenções de mapeamento ao definir seu modelo de objeto, sua única opção é a API Fluent.

Aprender a API Fluent é quase um must, os DataAnnotations são úteis para aplicativos simples.

Slauma
fonte
2
Eu sou um novato neste campo. A API Fluent pode ser usada para validar interfaces de usuário como DataAnnotation pode fazer?
beije minha axila em
27
@CounterTerrorist: Acho que não. Por exemplo: Se você colocar o [Required]atributo em uma propriedade em um aplicativo ASP.NET MVC, ele será usado tanto pelo EF quanto pelo MVC para fins de validação, porque ambos podem processar esse atributo. Mas o MVC não entenderá a configuração da API Fluent. Portanto, se você remover o atributo e usar HasRequiredna API Fluent, para EF será o mesmo, mas não para MVC. (Na minha opinião, os atributos deveriam ter nomes diferentes, o uso do namespace DataAnnotations de diferentes componentes e para diferentes propósitos é muito confuso.)
Slauma
4
Observe também que [DefaultValue()]não é possível no Fluent Either.
webnoob
4
MinValue é um atributo que não pode ser definido via API Fluent (Programming Entity Framework: Code First) (fonte: NAA excluído por The Cog )
Serge Ballesta
7
De um ponto de vista arquitetônico, acho Fluent APIque manteria sua lógica de implementação DbContexte a sua POCOlimpa
Luke T O'Brien