Problem with Valueobject in the Entity framework

Asked

Viewed 310 times

3

I’m having a hard time with a mapping and I’d like to know if it’s possible to do that:

I have a Contact class with two fields that are Valueobject type "Phone", the fields are Phone and Mobile.

public Telefone Telefone { get; set; }
public Telefone Celular { get; set; }

I would like to do the following mapping, so that Phone is mandatory and mobile is not:

Property(x => x.Telefone.DDD)
  .HasColumnName("TelefoneDDD")
  .IsRequired();
Property(x => x.Telefone.Numero)
  .HasColumnName("Telefone")
  .IsRequired();
Property(x => x.Celular.DDD)
  .HasColumnName("CelularDDD")
  .IsOptional();
Property(x => x.Celular.Numero)
  .HasColumnName("Celular")
  .IsOptional();

When I have Migration generated, it returns the following error:

Conflicting Configuration Settings Were specified for Property 'Numero' on type 'Sistemateste.domain.Valueobject.Phone': Isnullable = False Conflicts with Isnullable = True

  • Note: If I put all as Isoptional or Isrequired they work.

  • You could put in your question the definition of the complex object Telefone?

2 answers

0


You should have a separate setting for the Phone entity and just make the key for the two fields in your main entity. In one of them you leave as Obligatory and the other not

public class Telefone
{
    public int Codigo {get;set;}
    public int DDD {get;set;}
    public string Numero {get;set;}
}

public class Cadastro
{
    public int CodigoTelefone {get;set;}
    public Telefone Telefone {get;set;}
    public int? CodigoCelular {get;set;}
    public Telefone Celular {get;set;}
}

//Mapeamento da classe Cadastro

HasRequired(c => c.Telefone)
    .WithMany()
    .HasForeignKey(c => c.CodigoTelefone)
    .WillCascadeOnDelete(true); // Telefone é obrigatório

HasOptional(c => c.Celular)
    .WithMany()
    .HasForeignKey(c => c.CodigoCelular)
    .WillCascadeOnDelete(true); // Celular não é obrigatório
  • I understood how to do it this way, but I would not like to generate another table in the database, I would like to generate these fields in my contact table. Use it as Valueobject. Another option would be to throw them directly into my contact class and make the validations, but would run away from the concept they would like to use.

  • If you create the class Cell Phone inheriting maybe it works. I can’t tell you. Both would be a Phone class and you could do the mapping this way that is already done today (suspect). take the test and tell us ^^

  • It works, although it still doesn’t stay the way I expected it to be, it’s an alternative. I wonder if for some reason I create a more complex Valueobject and need to use it with different mappings for other classes, I will always have to create inherited classes to get around it. E.g.: A CPF may be mandatory for a client table and optional in an X table if I work with primitive type just validating is ok, but if I want to create a class to encapsulate the CPF I will bump into this problem again.

0

The solution to this problem really is not elegant. According to that question open in the Github of the Entity Framework there is a limitation on how it maps entities in its conceptual model (C-Space).

Note: The answer on Github is after this question and so I found it interesting to post here.

The solution I’ve been using is very similar to the one that Gabriel.santos suggested: create value Objects (VO) that are subclasses of other VO and configure only subclasses according to the needs of each entity. Ex.:

// classes
public class Telefone { /*...* /} 
public class TelefoneFixo : Telefone { /**/ }
public class TelefoneCelular : Telefone  { /**/ }

// propriedades de Contato
public TelefoneFixo Telefone { get; set; }
public TelefoneCelular Celular { get; set; }

// a configuração da entidade permanece inalterada

[Addendum] There are other contortible problems regarding the mapping of entities that use complex types as VO: it is not possible to use properties of a complex type in primary keys, in the composition of relationships (FK) or as a parameter for the Addorupdate method.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.