Duvida para Comparar Objetos C#

723 views
Skip to first unread message

Anderson Mariani

unread,
Jul 16, 2012, 3:01:00 PM7/16/12
to dotn...@googlegroups.com
Pessoal boa tarde estou com uma duvida eu tenho que comparar o objeto para saber se algum de suas propriedades foi alterado porém quando eu populo o 1 Objeto automaticamente ele passa as propriedades para o 2º, ou seja , se eu alterar o nome do objeto 1 ele altera do objeto 2 segue o código

              
               //Obtenho o 1º Objeto
                PremiacaoAluno aluno = new PremiacaoAlunoDAO().Obter(this.AlunoID);

               //Populo o Objeto com os campos atuais que vem da Tela do Usuário

                aluno.TurmaID = Convert.ToInt32(ddlTurma.SelectedValue);
                aluno.NomeCompleto = txtNome.Text;
                aluno.NumeroChamada = !string.IsNullOrEmpty(txtNumeroChamada.Text) ? Convert.ToInt32(txtNumeroChamada.Text) : 0;
                aluno.OrigemAlunoID = Convert.ToInt32(ddlOrigemAluno.SelectedValue);
                aluno.SituacaoMatriculaID = Convert.ToInt32(ddlSituacaoMatricula.SelectedValue);
                aluno.UsuarioOperacao = Convert.ToInt32(Session["UsuarioID"]);
                aluno.DataOperacao = DateTime.Now;
                aluno.TipoOperacao = 'A';

                //Obtenho o mesmo objeto para realizar a comparação
                PremiacaoAluno aluno2 = new PremiacaoAlunoDAO().Obter(this.AlunoID);


                if (!aluno.Equals(aluno2)) {
                    aluno.ValidarAlterar();
                    new PremiacaoAlunoDAO().Alterar(aluno);
                    Master.RetornarMensagem("Aluno Alterado com Sucesso!",false);
                
                
                }

O resultado fala que sempre os objetos são iguais.
--
Atenciosamente,

Anderson Candido Mariani
Analista de Sistemas
(67)8466-7748

Alan R. Lima

unread,
Jul 16, 2012, 3:13:40 PM7/16/12
to dotn...@googlegroups.com
Anderson,

O que o método obter faz ? Busca os valores do aluno no banco e criar um novo objeto com esses valores ?
Ou tem um cache que retorna esse aluno ?



--
==============================
Comunidade de desenvolvedores Dot Net no Brasil
 
WebSite: www.dotnetbr.com
 
E-mail do Grupo: dotn...@googlegroups.com
==============================

Anderson Mariani

unread,
Jul 16, 2012, 3:17:41 PM7/16/12
to dotn...@googlegroups.com
O metodo obter recupera a instancia de objeto que tou trabalhando eu passo o id por QueryString para o PremiacaoAlunoDAO o metodo this.AlunoID faz:

 public int AlunoID
        {
            get
            {

                if (ViewState["AlunoID"] == null)
                    return 0;
                else
                    return Convert.ToInt32(ViewState["AlunoID"]);
            }
            set
            {
                ViewState["AlunoID"] = value;
            }
        }

que chama o Obter


[System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Select, true)]
        public PremiacaoAluno Obter(int AlunoID)
        {
            try
            {
                var consulta = (from tab in SEDTIDataContext.PremiacaoAlunos
                                where tab.AlunoID == AlunoID
                                select tab);

                return consulta.SingleOrDefault();
            }
            catch (Exception)
            {
                throw;

dm.ga...@gmail.com

unread,
Jul 16, 2012, 3:08:23 PM7/16/12
to dotn...@googlegroups.com
De quem herda o PremiacaoAluno? Vc fez override do equals?


Deivison M. Gandini
dm.ga...@gmail.com | msn: dm_ga...@hotmail.com
Before printing, think about your responsibility and commitment to the ENVIRONMENT!
Antes de imprimir pense em sua responsabilidade e compromisso com o MEIO AMBIENTE!


2012/7/16 Anderson Mariani <andersoncan...@gmail.com>

dm.ga...@gmail.com

unread,
Jul 16, 2012, 3:38:52 PM7/16/12
to dotn...@googlegroups.com

1) Acho que seu objecto está sendo cacheado. Eu tentaria resolver isso em primeiro lugar

2)  No LinqToSql vc pode criar uma classe para  usar Observer das entidades do banco.
Segue os exemplos abaixo. Mas eu não faria essa sua checagem na interface UI.
/// <summary>
    /// This class observes any change in a object that implements INotifyPropertyChanged
    /// </summary>
    internal class ChangesWatcher : IDisposable
    {
        #region Properties
 
        /// <summary>
        /// The observed object.    
        /// </summary>
        INotifyPropertyChanged Observer { getset; }
 
        /// <summary>
        /// Indicates if has any change in the Observer
        /// </summary>
        public bool HasAnyChange { getprivate set; }
 
        #endregion
 
        #region Constructor
 
        /// <summary>
        /// Creates a new instance of ChangesWatcher
        /// </summary>
        /// <param name="Observer">
        /// </param>
        public ChangesWatcher(INotifyPropertyChanged observer)
        {
            HasAnyChange = false;
            (Observer = observer).PropertyChanged += new PropertyChangedEventHandler(Subject_PropertyChanged);
        }
 
        #endregion
 
        #region Methods
 
        /// <summary>     
        /// Occurs when a property value changes.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void Subject_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            HasAnyChange = true;
        }
 
        // TODO: Correct typo
        /// <summary>
        /// Resets any change
        /// </summary>
        public void Resest()
        {
            HasAnyChange = false;
        }
 
        #endregion
 
        #region IDisposable Members
 
        /// <summary>
        /// Releases allocated resources.
        /// </summary>
        public void Dispose()
        {
            Observer.PropertyChanged -= new PropertyChangedEventHandler(Subject_PropertyChanged);
        }
 
        #endregion
    }

Como utilizar

 using (var changesWatcher = new ChangesWatcher(aluno))
                        {

 aluno.TurmaID = Convert.ToInt32(ddlTurma.SelectedValue);
                aluno.NomeCompleto = txtNome.Text;
                aluno.NumeroChamada = !string.IsNullOrEmpty(txtNumeroChamada.Text) ? Convert.ToInt32(txtNumeroChamada.Text) : 0;
                aluno.OrigemAlunoID = Convert.ToInt32(ddlOrigemAluno.SelectedValue);
                aluno.SituacaoMatriculaID = Convert.ToInt32(ddlSituacaoMatricula.SelectedValue);
                aluno.UsuarioOperacao = Convert.ToInt32(Session["UsuarioID"]);
                aluno.DataOperacao = DateTime.Now;
                aluno.TipoOperacao = 'A';

 
                            if (changesWatcher.HasAnyChange){
                              
 aluno.ValidarAlterar();
                    new PremiacaoAlunoDAO().Alterar(aluno);
}
                        }





Deivison M. Gandini
dm.ga...@gmail.com | msn: dm_ga...@hotmail.com
Before printing, think about your responsibility and commitment to the ENVIRONMENT!
Antes de imprimir pense em sua responsabilidade e compromisso com o MEIO AMBIENTE!


2012/7/16 Anderson Mariani <andersoncan...@gmail.com>
O metodo obter recupera a instancia de objeto que tou trabalhando eu passo o id por QueryString para o PremiacaoAlunoDAO o metodo this.AlunoID faz:

Anderson Mariani

unread,
Jul 16, 2012, 4:08:24 PM7/16/12
to dotn...@googlegroups.com
Ok obrigado eu vou testar aqui

Leandro Sá

unread,
Jul 16, 2012, 4:20:05 PM7/16/12
to dotn...@googlegroups.com
Bom, acredito que seja uma questão de conceito(posso estar errado).

Como o resultado de sua consulta é sempre um objeto, na segunda vez um objeto com referencia ao anterior vai ser retornado. 

Você precisará criar um novo objeto a cada consulta, usando um new. Isso irá gerar um novo objeto e suas alterações vão ser únicas para cada objeto. Porém sua comparação com não irá funcionar, ao menos que você sobrescreva o metódo "Equals"

Abraço.

VINICUS VIEIRA

unread,
Jul 16, 2012, 4:34:16 PM7/16/12
to dotn...@googlegroups.com
Bother,
Tenta esse método abaixo, ele compara propriedade por propriedade da
classe e retorna se alguma estiver diferente.
É só você colocar em uma classe pai e herdar todas dela. Que todos os
equals vão retornar do jeito que você quer.
No seu caso retorna diferente por que o algoritmo do framework inclui
o espaço de memória na comparação, sendo assim ainda que os todos
objetos sejam idênticos em seus dados eles estão em dois espaços de
memória diferente por isso retorna diferente.
Para esse meu método você vai precisar de uma annotation que eu criei
para marcar quando uma propriedade não deve ser considerada na
comparação. você coloca sobre ela [isComparible(false)] e pronto o
equals não compara ela. Em seguida tem o código dela também. Não é a
solução mais elegante, mas é bem funcional. Espero ter ajudado.
Abraços.

public override bool Equals(object obj)
{
if (obj==null||GetType() != obj.GetType())
{
return false;
}

System.Reflection.PropertyInfo[] campos = GetType().GetProperties();

for (int i = 0; i < campos.Length; i++)
{
bool comparavel = true;
Object[] AttArray =
campos[i].GetCustomAttributes(typeof(Annotations.IsComparable),
false);
if (AttArray.Length > 0)
{
Annotations.IsComparable objIsCompar =
(Annotations.IsComparable)AttArray[0];
comparavel = objIsCompar.COMPARAVEL;
}
if (comparavel)
{
if (campos[i].GetValue(this, null) == null) {
if (campos[i].GetValue(obj, null) != null)
return false;
}

if (!campos[i].GetValue(this,
null).Equals(campos[i].GetValue(obj, null)))
return false;
}
}

return true;
}
//Annotation
[AttributeUsage(AttributeTargets.Property)]

public class IsComparable : System.Attribute
{

private bool Comparavel;


public IsComparable(bool Comparavel)
{
this.Comparavel = Comparavel;
}

public bool COMPARAVEL {
get { return Comparavel; }
set { Comparavel = value; }

Anderson Mariani

unread,
Jul 16, 2012, 4:42:17 PM7/16/12
to dotn...@googlegroups.com
ok vou tentar esse metodo vlw

Leandro Sá

unread,
Jul 18, 2012, 2:55:07 PM7/18/12
to dotn...@googlegroups.com
E ai amigo, conseguiu resolver o problema?

Anderson Mariani

unread,
Jul 18, 2012, 3:05:34 PM7/18/12
to dotn...@googlegroups.com
Na verdade não pq o meu chefe quis que ficasse assim msm é pq eu tenho uma trigger para alimentar uma tabela de auditoria que é alimentada por exemplo se o cara entrasse para alterar o aluno e não alterasse nada e mandasse alterar ficaria que foi alterado e quando na verdade não foi modificado nada eu queria fazer essa comparação pra isso para não gerar esses dados, mas aqui no serviço se o cara mandar alterar sem ter alterado nada é para ficar o registro na minha tabela de auditoria.

Leandro Sá

unread,
Jul 18, 2012, 3:07:02 PM7/18/12
to dotn...@googlegroups.com
Ok. 

Qualquer coisa estamos ai.

[]'s

Anderson Mariani

unread,
Jul 18, 2012, 3:09:19 PM7/18/12
to dotn...@googlegroups.com
Blza
Reply all
Reply to author
Forward
0 new messages