Fazendo AddOrUpdate alterar apenas algumas propriedades
Essa pode ser uma pergunta simples, no entanto, eu sou novo no Code First e as Migrações me acompanham. Vou manter o código de amostra no mínimo para mostrar o problema:
eu tenho umBaseAuditableEntity
que inclui isso (entre outras coisas, mas vamos simplificar):
public abstract class BaseAuditableEntity : BaseEntity, IAuditableEntity
{
public DateTime CreatedOn { get; set; }
public DateTime LastModified { get; set; }
}
Agora um (por exemplo)User
O POCO herda dele:
public class User : BaseAuditableEntity
{
public string UserName { get; set; }
public string PasswordHash { get; set; }
public string FullName { get; set; }
public string Email { get; set; }
public bool Active { get; set; }
public DateTime? LastLogin { get; set; }
}
Eu tenho isso no meu contextoSaveChanges
método, para preencher oCreatedOn
eLastModified
datas (simplificadas):
public override int SaveChanges()
{
var changeSet = ChangeTracker.Entries<IAuditableEntity>();
if (changeSet != null)
{
foreach (var entry in changeSet.Where(p => p.State != EntityState.Unchanged))
{
var now = DateTime.UtcNow;
if (entry.State == EntityState.Added)
entry.Entity.CreatedOn = now;
entry.Entity.LastModified = now;
}
}
return base.SaveChanges();
}
E agora eu tenho uma migração em andamento que semeia alguns usuários, como este:
protected override void Seed(MyContext context)
{
context.Users.AddOrUpdate(
p => p.UserName,
new User { Active = true,
FullName = "My user name",
UserName = "ThisUser",
PasswordHash = "",
Email = "my@email",
LastLogin = null,
}
// etc.
);
}
Agora eu tenho um problema ao semear comAddOrUpdate
após a migração. Quando a entidade é nova (está sendo adicionada),CreatedOn
é preenchido corretamente e tudo funciona como esperado. No entanto, quando a entidade é modificada (ela já existe no banco de dados eUserName
corresponde), tenta atualizá-lo com a nova entidade que estou criando ... isso falha porqueCreatedOn
tem um inválidoDateTime
(nesse caso,DateTime.MinValue
)
Existe alguma maneira de usar oAddOrUpdate
método para que ele realmente recupere a entidade correspondente do banco de dados e apenas atualize os campos não padrão? Ou talvez alguma maneira de dizer quais campos NÃO devem ser atualizados? Para este caso específico, eu gostaria doCreatedOn
campo inalterado, mas uma solução genérica seria apreciada.
Talvez eu deva fazer o meu próprioAddOrUpdate
método que inclui um predicado com os campos que quero alterar, em vez de transmitir uma entidade completamente nova?
Este é o EF 6.1
AtualizarEu sei que posso resolver isso facilmente para oCreatedOn
data, é o que estou fazendo atualmente para este caso específico:
foreach (var entry in changeSet.Where(c => c.State != EntityState.Unchanged))
{
var now = DateTime.UtcNow;
if (entry.State == EntityState.Added)
{
entry.Entity.CreatedOn = now;
}
else
{
if (entry.Property(p => p.CreatedOn).CurrentValue == DateTime.MinValue)
{
var original = entry.Property(p => p.CreatedOn).OriginalValue;
entry.Property(p => p.CreatedOn).CurrentValue = original != SqlDateTime.MinValue ? original : now;
entry.Property(p => p.CreatedOn).IsModified = true;
}
}
entry.Entity.LastModified = now;
}
Estou procurando uma solução mais genérica