Entityframework type conversion error: Cannot convert a 'System.Collections.Generic.Hashset`1[]' object

Asked

Viewed 1,395 times

1

I am getting this error while trying to record a new record of Atendimento.

Cannot convert an object of type 'System.Collections.Generic.Hashset`1[Domain.Servicesinexus]' in type 'Domain.Servicesinexus'.

Classes:

Attending:

public class Atendimento
{
    public Atendimento()
    {
        Historicos = new HashSet<AtendimentoHistorico>();
        Anexos = new HashSet<AtendimentoAnexo>();
        Variaveis = new HashSet<Variavel>();
    }

    [Key]
    [Required]
    [Column(Order = 0)]
    [ForeignKey("Revenda")]
    public int RevendaId { get; set; }
    public virtual Revenda Revenda { get; set; }

    [Key]
    [Required]
    [Column(Order = 1)]
    public int EmpresaId { get; set; }
    [ForeignKey("RevendaId, EmpresaId")]
    public virtual Empresa Empresa { get; set; }

    [Key]
    [Column(Order = 2)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int Id { get; set; }

    public int? ClienteId { get; set; }
    [ForeignKey("RevendaId, EmpresaId, ClienteId")]
    public virtual Cliente Cliente { get; set; }

    [Required]
    [ForeignKey("Departamento")]
    public int DepartamentoId { get; set; }
    public virtual Departamento Departamento { get; set; }

    [Required]
    public int AssuntoId { get; set; }
    [ForeignKey("DepartamentoId, AssuntoId")]
    public virtual Assunto Assunto { get; set; }

    [Required]
    [ForeignKey("SituacaoAtendimento")]
    public int SituacaoId { get; set; }
    public TipoSituacaoAtendimento SituacaoAtendimento { get; set; }

    [StringLength(150)]
    [ForeignKey("UsuarioCriador")]
    public string UsuarioCriadorLogin { get; set; }
    public virtual Usuario UsuarioCriador { get; set; }

    [StringLength(150)]
    [ForeignKey("UsuarioSolicitante")]
    public string UsuarioSolicitanteLogin { get; set; }
    public virtual Usuario UsuarioSolicitante { get; set; }

    [StringLength(150)]
    [ForeignKey("UsuarioResponsavel")]
    public string UsuarioResponsavelLogin { get; set; }
    public virtual Usuario UsuarioResponsavel { get; set; }

    [StringLength(250)]
    [Column(TypeName = "text")]
    [DataType(DataType.MultilineText)]
    [Required(AllowEmptyStrings = false)]
    public string Descricao { get; set; }

    [StringLength(250)]
    [Column(TypeName = "text")]
    [DataType(DataType.MultilineText)]
    public string Solucao { get; set; }

    [Required]
    public DateTime DataHoraSolicitacao { get; set; }

    public DateTime? DataHoraPrevistaEncerramento { get; set; }
    public DateTime? DataHoraEncerramento { get; set; }

    [StringLength(50)]
    [Required(AllowEmptyStrings = false)]
    public string MeioAcesso { get; set; }

    [InverseProperty("Atendimento")]
    public virtual ICollection<AtendimentoHistorico> Historicos { get; set; }

    [InverseProperty("Atendimento")]
    public virtual ICollection<AtendimentoAnexo> Anexos { get; set; }

    [InverseProperty("Atendimento")]
    public virtual ICollection<Variavel> Variaveis { get; set; }
}

Helpnexo:

public class AtendimentoAnexo
{
    [Key]
    [Column(Order = 0)]
    [ForeignKey("Revenda")]
    public int RevendaId { get; set; }
    public virtual Revenda Revenda { get; set; }

    [Key]
    [Column(Order = 1)]
    public int EmpresaId { get; set; }
    [ForeignKey("RevendaId, EmpresaId")]
    public virtual Empresa Empresa { get; set; }

    [Key]
    [Column(Order = 2)]
    public int AtendimentoId { get; set; }
    [ForeignKey("RevendaId, EmpresaId, AtendimentoId")]
    public virtual Atendimento Atendimento { get; set; }

    [StringLength(250)]
    [Required(AllowEmptyStrings = false)]
    public string UrlArquivo { get; set; }
}

Excerpt from the record:

var atendimento = new Domain.Atendimento();

using (var transaction = _context.Database.BeginTransaction())
{
    try
    {
        #region carrega atendimento ...

        atendimento.RevendaId = UsuarioLogado.RevendaId;
        atendimento.EmpresaId = UsuarioLogado.EmpresaId ?? 0;

        if (txtId.Text.IsPopulated())
            atendimento.Id = Convert.ToInt32(txtId.Text.Replace(".", ""));

        if (txtDataSolicitacao.Text.IsPopulated() && txtHoraSolicitacao.Text.IsPopulated())
            atendimento.DataHoraSolicitacao = Convert.ToDateTime(txtDataSolicitacao.Text +
                " " + txtHoraSolicitacao.Text + ":00");

        if (ddlCliente.SelectedValue.IsPopulated())
            atendimento.ClienteId = Convert.ToInt32(ddlCliente.SelectedValue);

        if (ddlDepatamento.SelectedValue.IsPopulated())
            atendimento.DepartamentoId = Convert.ToInt32(ddlDepatamento.SelectedValue);

        if (ddlAssunto.SelectedValue.IsPopulated())
            atendimento.AssuntoId = Convert.ToInt32(ddlAssunto.SelectedValue);

        if (ddlSolicitante.SelectedValue.IsPopulated())
            atendimento.UsuarioSolicitanteLogin = ddlSolicitante.SelectedValue;

        atendimento.UsuarioCriadorLogin = UsuarioLogado.Login;

        if (UsuarioLogado.GrupoAcesso != Domain.GrupoAcesso.Cliente)
            atendimento.UsuarioResponsavelLogin = atendimento.UsuarioCriadorLogin;

        if (ddlMeioAcesso.SelectedValue.IsPopulated())
            atendimento.MeioAcesso = ddlMeioAcesso.SelectedValue;

        if (ddlSituacao.SelectedValue.IsPopulated())
            atendimento.SituacaoId = Convert.ToInt32(ddlSituacao.SelectedValue);

        var status = _context.TiposSituacaoAtendimento
            .SingleOrDefault(x => x.Id == atendimento.SituacaoId);
        if (status != null && status.Status == "2")
        {
            atendimento.DataHoraEncerramento = DateTime.Now;
            atendimento.Solucao = txtDescricao.Text;
        }

        atendimento.Descricao = txtDescricao.Text;

        #endregion carrega atendimento ...

        _context.Atendimentos.Add(atendimento); // O erro acontece aqui
        _context.SaveChanges();

Detail that at that moment I have not yet managed to feed the property Anexos class Atendimento.

Previously the properties of the list type were declared as List<T> and giving the same kind of mistake. So I went to ICollection<T> to test, as it is the most frequently used type.

What could be causing this problem?


As the error message shows, it is clear that Entityframework is treating my property as not being of the list type.

EntityFramework Avacalhando

And with that condition plays the flow to TakeSnapshotOfSingleRelationship.

var navigationProperties =
    (metadata.CdmMetadata.EdmType as EntityType).NavigationProperties;

foreach (var n in navigationProperties)
{
    var relatedEnd = rm.GetRelatedEndInternal(n.RelationshipType.FullName, n.ToEndMember.Name);
    var val = WrappedEntity.GetNavigationPropertyValue(relatedEnd);

    if (val != null)
    {
        if (n.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many)
        {
            ...
        }
        else
        {
            // Reference
            TakeSnapshotOfSingleRelationship(relatedEnd, n, val);
        }
    }
}
  • only one Obs: Hashset is slower eim.. rsrss

  • @Rod, I didn’t know that. Oh why?

  • When you make a database-first or model-first, or a reverse with Entityframework Power Tools, VS generates with this type.

  • 1

    http://stackoverflow.com/questions/150750/hashset-vs-list-performance

  • 1

    @Rod, this graph confused me.. by looking directly at it alone, I understand that as the size of records and objects grows, List<T> tends to take much longer.

  • 1

    I also saw this @Tiagosilva, and it is what the author wrote also, that the List is faster up to 20 objects

  • @Caputo, grateful! Now I understand! = D

  • 1

    However.. and in the Entityframework, internally, is worth thinking about, where to put [List<T>](null) and where to put HashSet<T>? This does not change the way Entityframework works? ;]

Show 3 more comments

1 answer

2

Identifying that the Entityframework I was treating my property as a simple relationship (Zero or One, as the image shows) and then generating the error, I changed my approach to that of much already discussed in the questions about Entityframework.

public class AtendimentoAnexo
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [Index("unq_AtendimentoAnexo", IsUnique = true, Order = 1)]
    [ForeignKey("Revenda")]
    public int RevendaId { get; set; }
    public virtual Revenda Revenda { get; set; }

    [Index("unq_AtendimentoAnexo", IsUnique = true, Order = 2)]
    public int EmpresaId { get; set; }
    [ForeignKey("RevendaId, EmpresaId")]
    public virtual Empresa Empresa { get; set; }

    [Index("unq_AtendimentoAnexo", IsUnique = true, Order = 3)]
    public int AtendimentoId { get; set; }
    [ForeignKey("RevendaId, EmpresaId, AtendimentoId")]
    public virtual Atendimento Atendimento { get; set; }

    [StringLength(250)]
    [Required(AllowEmptyStrings = false)]
    public string UrlArquivo { get; set; }
}

And with that the problem was solved.

The mistake was to have only these fields as the primary key:

[Key]
[Column(Order = 0)]
[ForeignKey("Revenda")]
public int RevendaId { get; set; }
public virtual Revenda Revenda { get; set; }

[Key]
[Column(Order = 1)]
public int EmpresaId { get; set; }
[ForeignKey("RevendaId, EmpresaId")]
public virtual Empresa Empresa { get; set; }

[Key]
[Column(Order = 2)]
public int AtendimentoId { get; set; }
[ForeignKey("RevendaId, EmpresaId, AtendimentoId")]
public virtual Atendimento Atendimento { get; set; }

Without a differentiator, how would you have more than one record of the same service? An extra field in the key would also solve.

Browser other questions tagged

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