Pergunta

Entidades de auto -rastreamento. Incrível.

Exceto quando você faz algo como

return Db.Users;

Nenhuma das entidades de auto-rastreamento está rastreando (até que, possivelmente, elas sejam desserializadas).

Multar. Portanto, temos que reconhecer que existe a possibilidade de que uma entidade retorne a nós não tenha rastreamento ativado.

O que agora???

Coisas que eu tentei

Para o corpo do método especificado:

using (var db = new Database())
{
    if (update.ChangeTracker.ChangeTrackingEnabled)
        db.Configurations.ApplyChanges(update);
    else
        FigureItOut(update, db);

    db.SaveChanges();
    update.AcceptChanges();
}

As seguintes implementações de FigureItOut Tudo falha:

db.Configurations.Attach(update);
db.DetectChanges();

Nem

db.Configurations.Attach(update);
db.Configurations.ApplyCurrentValues(update);

Nem

db.Configurations.Attach(update);
db.Configurations.ApplyOriginalValues(update);

Nem

db.Configurations.Attach(update);
db.Configurations.ApplyChanges(update

Nem sobre mais nada que eu possa imaginar para jogar, exceto

  1. Obtendo a entidade original do banco de dados
  2. Comparando cada propriedade manualmente
  3. Atualizando propriedades conforme necessário

O que, exatamente, devo fazer com entidades auto-rastreadas que não estão se rastreando?


Pequena atualização:

Marcar cegamente a entidade como obras modificadas, no entanto, isso parece um pouco fedorento. É o melhor que podemos fazer neste caso?

Foi útil?

Solução

Cenário 1

Aqui estão algumas práticas recomendadas a seguir. Quando você está usando o STE no cenário WCF, você deve confiar no rastreador de mudança que o STE implementa para que, no lado do servidor, você faça o seguinte.

db.Users.ApplyChanges(user);
db.SaveChanges();

Cenário 2 No entanto, se você estiver no servidor, a prática recomendada é criar um método na classe parcial para o ObjectContext chamado EnableChangeTracking. O método consultaria as entidades que estão em indicação inalterada que implementa o IObjectwithChangeTracker e liga o rastreamento de alterações, então algo assim

user = db.users.first(u => u.userid == 1);
db.EnableChangeTracking();

Agora tente salvar a entidade do usuário de um contexto diferente do qual foi originalmente recuperado

db2.users.ApplyChanges(user);
db2.SaveChanges();

Cenário 3 Se no lado do servidor você estiver conectado ao mesmo contexto de objeto a partir do qual você recuperou a entidade do usuário, então você usa o sTE como objeto poco simples como abaixo

user = db.users.first(u => u.userid == 1);
user.LastName = "XYZ";
db.DetectChanges(); //no need for it cuz Savechanges implicitly calls this.
db.SaveChanges();

Cenário 4 Se a entidade do usuário for recuperada de um contexto diferente, o contexto que você usará para salvar, aqui está outra opção em que você marcará a entidade como modificada e não se importará com o que foi modificado.

user = db.users.first(u => u.userid == 1);
var db2 = new ObjectContext();
user.LastName = "XYZ";
db2.Users.Attach(user);
// i prefer this option..
db2.ObjectStateManager.ChangeObjectState(user,EntityState.Modified); 
db2.SaveChanges(); // updates all columns

Cenário 5 Se a entidade do usuário for recuperada de um contexto diferente, o contexto que você usará para salvar, aqui está outra opção em que você recupera a entidade original.

user = db.users.first(u => u.userid == 1);
user.lastName ="XYZ";
var db2 = new ObjectContext();
db2.Users.First(u => u.userid == user.userid);
db2.users.ApplyCurrentValues(user);
db2.SaveChanges();

Aqui está um post de blog que descreve poucos cenários.http://weblogs.asp.net/zeeshanhirani/archive/2010/03/30/modifying-self-tracking-entity-on-the-sherver.aspx

Eu cobro extensivamente esses conceitos em minha estrutura de entidade 4.0 Receitas, com muitos cenários.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top