0
When editing a record and saving for the first time entityframework performs the update successfully, but when I click again on edit and save the record I come across the following error:
Error saving record: Attaching an Entity of type 'Projeto.WebERP.Entityframework.Entities.Cadastros.Localidade.Cidade' failed because Another Entity of the same type already has the same Primary key value. This can happen when using the 'Attach' method or Setting the state of an Entity to 'Unchanged' or 'Modified' if any entities in the Graph have Conflicting key values. This may be because some entities are new and have not yet Received database-generated key values. In this case use the 'Add' method or the 'Added' Entity state to track the Graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate.
What am I doing wrong?
Repositoriobase
public abstract class RepositorioBase<TEntity> : IRepositorioCRUD<TEntity>, IRepositioSQL<TEntity>
where TEntity : EntityBase
{
public RepositorioBase()
{
_context = new ProjetoContext();
}
ProjetoContext _context;
public long GetNextHandle()
{
var instance = Activator.CreateInstance<TEntity>();
var tabela = instance.GetType().Name.ToUpper();
var handle = _context.Database.SqlQuery<long>("SELECT (COALESCE(MAX(HANDLE),0) + 1) HANDLE FROM " + tabela).ToArray();
return Convert.ToInt64(handle[0]);
}
public long Inserir(TEntity entity)
{
try
{
entity.Handle = GetNextHandle();
_context.Set<TEntity>().Attach(entity);
_context.Entry(entity).State = System.Data.Entity.EntityState.Added;
var erros = _context.GetValidationErrors();
if (erros.Count() > 0)
{
string stringErro = string.Empty;
foreach (var erro in erros)
foreach (var er in erro.ValidationErrors)
stringErro += string.Format(er.ErrorMessage.ToString() + " {0}", Environment.NewLine);
if (!string.IsNullOrEmpty(stringErro))
throw new Exception(stringErro);
}
return _context.SaveChanges();
}
catch (Exception erro)
{
throw new Exception(erro.Message);
}
}
public virtual bool Atualizar(TEntity entity)
{
try
{
_context.Set<TEntity>().Attach(entity);
_context.Entry(entity).State = System.Data.Entity.EntityState.Modified;
var erros = _context.GetValidationErrors();
if (erros.Count() > 0)
{
string stringErro = string.Empty;
foreach (var erro in erros)
foreach (var er in erro.ValidationErrors)
stringErro += string.Format(er.ErrorMessage.ToString() + " {0}", Environment.NewLine);
if (!string.IsNullOrEmpty(stringErro))
throw new Exception(stringErro);
}
_context.SaveChanges();
return true;
}
catch (Exception erro)
{
throw new Exception(erro.Message);
}
}
public bool Deletar(TEntity entity)
{
try
{
_context.Set<TEntity>().Attach(entity);
_context.Entry(entity).State = System.Data.Entity.EntityState.Deleted;
var erros = _context.GetValidationErrors();
if (erros.Count() > 0)
{
string stringErro = string.Empty;
foreach (var erro in erros)
foreach (var er in erro.ValidationErrors)
stringErro += string.Format(er.ErrorMessage.ToString() + " {0}", Environment.NewLine);
if (!string.IsNullOrEmpty(stringErro))
throw new Exception(stringErro);
}
_context.SaveChanges();
return true;
}
catch (Exception erro)
{
throw new Exception(erro.Message);
}
}
public IQueryable<TEntity> GetAll()
{
return _context.Set<TEntity>().AsNoTracking().AsQueryable();
}
public IQueryable<TEntity> Find(System.Linq.Expressions.Expression<Func<TEntity, bool>> where)
{
return _context.Set<TEntity>().AsNoTracking().Where(where).AsQueryable();
}
public TEntity GetByHandle(long handle)
{
return _context.Set<TEntity>().AsNoTracking().FirstOrDefault(x => x.Handle == handle);
}
public IQueryable<TResult> FindSelect<TResult>(Expression<Func<TEntity, TResult>> select, Expression<Func<TEntity, bool>> where)
{
return _context.Set<TEntity>().AsNoTracking().Where(where).Select(select).AsQueryable<TResult>();
}
}
City Registration Form
public partial class FormularioCidade : FormularioBase
{
public FormularioCidade()
{
InitializeComponent();
}
RepositorioBase<Pais> _RepositorioPais = new RepositorioPais();
RepositorioBase<Estado> _RepositorioEstado = new RepositorioEstado();
RepositorioBase<Cidade> _RepositorioCidade = new RepositorioCidade();
public override void LoadFormulario()
{
bsGrid.DataSource = ObterRegistrosParaGrid(x => x.Handle > 0).ToList();
}
public override void BotaoNovo()
{
bsCidade.AddNew();
PopularBSPais();
}
public override void BotaoEditar()
{
PopularBSPais();
PosicionarPais();
PosicionarEstado();
}
private IQueryable<object> ObterRegistrosParaGrid(Expression<Func<Cidade, bool>> where)
{
return _RepositorioCidade.FindSelect(x => new
{
Handle = x.Handle,
Descricao = x.Descricao,
Sigla = x.Sigla,
Estado = x.Estado,
EstadoHandle = x.Estado.Handle,
EstadoDescricao = x.Estado.Descricao,
Pais = x.Estado.Pais,
PaisHandle = x.Estado.Pais.Handle,
PaisDescricao = x.Estado.Pais.Descricao,
DataCadastro = x.DataCadastro,
DataAlteracao = x.DataAlteracao
}, where).AsQueryable();
}
public override void BotaoSalvar()
{
if (State == EntityState.Added)
{
Cidade currentCidade = (bsCidade.Current as Cidade);
Pais currentPais = (bsCidade.Current as Pais);
Estado currentEstado = (bsCidade.Current as Estado);
Cidade cidade = new Cidade();
cidade.Handle = _RepositorioCidade.GetNextHandle();
cidade.Descricao = currentCidade.Descricao;
cidade.Sigla = currentCidade.Sigla;
cidade.Estado = currentEstado;
cidade.EstadoHandle = currentEstado.Handle;
cidade.Estado.Pais = currentPais;
cidade.Estado.PaisHandle = currentPais.Handle;
cidade.DataAlteracao = null;
cidade.DataCadastro = DateTime.Now;
_RepositorioCidade.Inserir(cidade);
var newCidade = ObterRegistrosParaGrid(x => x.Handle == cidade.Handle).FirstOrDefault();
bsGrid.Add(newCidade);
}
else if (State == EntityState.Modified)
{
Cidade currentCidade = (bsCidade.Current as Cidade);
Pais currentPais = (bsPais.Current as Pais);
Estado currentEstado = (bsEstado.Current as Estado);
Cidade cidade = new Cidade();
cidade.Handle = currentCidade.Handle;
cidade.Descricao = currentCidade.Descricao;
cidade.Sigla = currentCidade.Sigla;
cidade.Estado = currentEstado;
cidade.EstadoHandle = currentEstado.Handle;
cidade.Estado.Pais = currentPais;
cidade.Estado.PaisHandle = currentPais.Handle;
cidade.DataAlteracao = DateTime.Now;
cidade.DataCadastro = currentCidade.DataCadastro;
_RepositorioCidade.Atualizar(cidade);
var newCidade = ObterRegistrosParaGrid(x => x.Handle == cidade.Handle).FirstOrDefault();
var indice = bsGrid.IndexOf(bsGrid.Current);
bsGrid.RemoveAt(indice);
bsGrid.Insert(indice, newCidade);
bsGrid.Position = indice;
}
}
public override void BotaoCancelar()
{
PopularCamposCadastro();
}
public override void BotaoExcluir()
{
Cidade cidade = (bsCidade.Current as Cidade);
_RepositorioCidade.Deletar(cidade);
var indice = bsGrid.IndexOf(bsGrid.Current);
bsGrid.RemoveAt(indice);
}
public override void BotaoPesquisar()
{
}
private void bsPais_CurrentChanged(object sender, EventArgs e)
{
long handlePais = (bsPais.Current as Pais).Handle;
PopularBSEstado(handlePais);
}
private void bsGrid_CurrentChanged(object sender, EventArgs e)
{
PopularCamposCadastro();
lblTotalRegistros.Text = string.Format("Registro {0} de {1}", bsGrid.IndexOf(bsGrid.Current) + 1, bsGrid.Count);
}
private void PopularCamposCadastro()
{
if (bsGrid.Current != null)
{
Cidade cidade = (bsGrid.Current as object).ToEntity<Cidade>();
Pais pais = (bsGrid.Current as dynamic).Pais;
Estado estado = (bsGrid.Current as dynamic).Estado;
bsCidade.DataSource = cidade;
bsPais.DataSource = pais;
bsEstado.DataSource = estado;
}
}
private void PopularBSPais()
{
bsPais.DataSource = _RepositorioPais.GetAll().ToList();
}
private void PopularBSEstado(long handlePais)
{
if (handlePais > 0)
{
bsEstado.DataSource = _RepositorioEstado.Find(x => x.PaisHandle == handlePais).ToList();
}
}
private void PosicionarPais()
{
if (bsGrid.Current != null)
{
long handlePais = (bsGrid.Current as dynamic).PaisHandle;
bsPais.Position = (bsPais.IndexOf((bsPais.List as List<Pais>).FirstOrDefault(x => x.Handle == handlePais)));
}
}
private void PosicionarEstado()
{
if (bsGrid.Current != null)
{
long handleEstado = (bsGrid.Current as dynamic).EstadoHandle;
bsEstado.Position = (bsEstado.IndexOf((bsEstado.List as List<Estado>).FirstOrDefault(x => x.Handle == handleEstado)));
}
}
}
City Class
[Serializable]
public class Cidade : EntityBase
{
public override long Handle { get; set; }
public string Descricao { get; set; }
public string Sigla { get; set; }
public long EstadoHandle { get; set; }
public virtual Estado Estado { get; set; }
public override DateTime DataCadastro { get; set; }
public override DateTime? DataAlteracao { get; set; }
}
Fluent API City Class
public class CidadeMap : EntityBaseTypeConfiguration<Cidade>
{
public override void ConfigureTableName()
{
ToTable("CIDADE");
}
public override void ConfigurePrimaryKey()
{
HasKey(x => x.Handle)
.Property(x => x.Handle).HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None);
}
public override void ConfigureForeingKeys()
{
HasRequired(p => p.Estado)
.WithMany(p => p.Cidades)
.HasForeignKey(p => p.EstadoHandle);
}
public override void ConfigureProperties()
{
Property(p => p.EstadoHandle)
.HasColumnName("ESTADOHANDLE")
.IsRequired();
Property(p => p.Descricao)
.IsRequired()
.HasMaxLength(150)
.HasColumnName("DESCRICAO");
Property(p => p.Sigla)
.IsRequired()
.HasMaxLength(3)
.HasColumnName("SIGLA");
}
public override void ConfigureHasMany()
{
}
}
Error remains friend.
– Nicola Bogar
Try to completely remove this line, see if the error persists.
– MurariAlex
which line you refer to ?
– Nicola Bogar
I updated my answer
– MurariAlex
worked out friend, could explain me better this way to update the record ?
– Nicola Bogar
I updated the answer with more information.
– MurariAlex