First let’s analyze whether the derivation of Pessoa
is a composition or an inheritance. As a Pessoa
cannot be both physical and legal at the same time, so it is a case of inheritance (a table represents the two entities). If it could, it would be a case of composition (a common table + 2 tables representing the data complement of each entity).
Therefore, a good modeling would be the following:
public class Pessoa
{
[Key]
public int PessoaId { get; set; }
[Required]
public String NomeOuRazaoSocial { get; set; }
}
public class PessoaFisica : Pessoa
{
[Required]
[Cpf] // Mais abaixo coloco a implementação desse atributo.
[Unico(ErrorMessage = "Já existe uma pessoa física com este CPF.", ModelType = typeof(PessoaFisica))] // Deste também.
public String Cpf { get; set; }
}
public class PessoaJuridica : Pessoa
{
[Required]
[Cnpj] // Mais abaixo coloco a implementação desse atributo.
[Unico(ErrorMessage = "Já existe uma pessoa jurídica com este CNPJ.", ModelType = typeof(PessoaJuridica))] // Deste também.
public String Cnpj { get; set; }
}
Here you go [Cnpj]
.
Here you go [Cpf]
.
UnicoAttribute.cs
Before implementing this attribute, install the System.Linq.Dynamic package:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class UnicoAttribute : ValidationAttribute
{
public Type ModelType { get; set; }
public UnicoAttribute() : base() { }
public UnicoAttribute(Type _modelType) : base()
{
ModelType = _modelType;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
using (MeuContext db = new MeuContext())
{
var Name = validationContext.MemberName;
if (string.IsNullOrEmpty(Name))
{
var displayName = validationContext.DisplayName;
var prop = validationContext.ObjectInstance.GetType().GetProperty(displayName);
if (prop != null)
{
Name = prop.Name;
}
else
{
var props = validationContext.ObjectInstance.GetType().GetProperties().Where(x => x.CustomAttributes.Count(a => a.AttributeType == typeof(DisplayAttribute)) > 0).ToList();
foreach (PropertyInfo prp in props)
{
var attr = prp.CustomAttributes.FirstOrDefault(p => p.AttributeType == typeof(DisplayAttribute));
var val = attr.NamedArguments.FirstOrDefault(p => p.MemberName == "Name").TypedValue.Value;
if (val.Equals(displayName))
{
Name = prp.Name;
break;
}
}
}
}
PropertyInfo IdProp = validationContext.ObjectInstance.GetType().GetProperties().FirstOrDefault(x => x.CustomAttributes.Count(a => a.AttributeType == typeof(KeyAttribute)) > 0);
var Id = (Guid)IdProp.GetValue(validationContext.ObjectInstance, null);
Type entityType = validationContext.ObjectType;
var result = db.Set(ModelType ?? entityType).Where(Name + "==@0", value);
int count = 0;
if (Id != Guid.Empty)
{
result = result.Where(IdProp.Name + "<>@0", Id);
}
count = result.Count();
if (count == 0)
return ValidationResult.Success;
else
return new ValidationResult(ErrorMessageString);
}
}
}
To migrate the data, you can build an SQL script with the table already created by Migrations or make a Seed. Seed is recommended for small data volumes. SQL script for large volumes.
If the path is by the SQL script, watch out for the filling of the column discriminator
with "Personal" or "Personal".
But Gypsy, how do I know if the person in my other system is physical or legal? I was thinking of creating a type of person
Outra
and store these people in this system in this entity, and over time update these records and transform them into Physical or Legal– Pablo Tondolo de Vargas
It is a good idea, but the conversion from "Other" to another type of person cannot be done by the EF. You will have to do a manual command updating the Discriminator.
– Leonel Sanches da Silva
I had in mind something like unifying the registers, like if I had people like another: Pablo, Pablo Vargas, Pablo de Vargas then I would create a register of individuals Pablo Tondolo de Vargas and unify the other types of registers. and would prevent using the other type of criminal records
– Pablo Tondolo de Vargas
So I think you would have to go to composition, not inheritance. If you want, I write one more answer.
– Leonel Sanches da Silva
Ta tranquilho Gypsy, my doubt even is not like doing at programming level. I’m gonna keep an inheritance anyway and create another entity inheriting a person and drop everything like it’s some kind of temporary.
– Pablo Tondolo de Vargas
@Ciganomorrisonmendez, regarding the validation of unique fields in the Database, would not be better to do this in the
DbContext.ValidateEntity
?– Tobias Mesquita
@Tobiasmesquita This answer is kind of old. If you want to do the version of
ValidateEntity
, we will thank!– Leonel Sanches da Silva