Usuário com melhor resposta
DataContext, classes diferentes para mesma tabela

Pergunta
-
Olá,
a muito tempo atrás já tinha perguntado sobre o isto, e naquele momento o problema foi resolvido.
Porém, fui atrás do post, e meu problema persiste, e vou mostrar aqui a situação:
Tenho o meu Context:
public class ERPCodeFirstContext : DbContext { public DbSet<Usuario> Usuario { get; set; } public ERPCodeFirstContext() { Database.SetInitializer<ERPCodeFirstContext>(null); } protected override void OnModelCreating(DbModelBuilder modelBuilder) { var _DBOwner = "dbo"; modelBuilder.Entity<Usuario>().ToTable("Usuario", schemaName: _DBOwner); } }
Ele tem o DBSet para Usuario, e está mapeado para usar a tabela Usuario no banco de dados.
Agora vem meu problema, tenho 5 classes para usuários, uma para validar, outra para que o cara esqueceu a senha e outra para ativação (que esta salva o campo DtAtivação) do usuário.
Porém como o DBSet está ligado com a classe Usuario, ao buscar os dados e alterar a DtAtivacao para um valor e tentar salvar, dá erro que alguns campos não foram informados.
Pois esta classe é usada para inserir um novo usuário.
Minha dúvida é, como sair desta sinuca de bico? Tem que criar 2 DBSet para a mesma tabela?
Ou criar uma super classe SuperUsuario e lá dentro vincular as outras classes?
public class UsuarioEsqueci { [Display(Name = "Login")] public string Login { get; set; } [Display(Name = "Senha")] public string Email { get; set; } } public class UsuarioConectar { [Required(ErrorMessage = "Obrigatório")] [Display(Name = "Login")] public string Login { get; set; } [Required(ErrorMessage = "Obrigatório")] [DataType(DataType.Password)] [Display(Name="Senha")] public string Senha { get; set; } } public class UsuarioAtivacao { [Key] public int UsuarioID { get; set; } public string Login { get; set; } public string Chave { get; set; } public Nullable<DateTime> DtAtivacao { get; set; } } public class Usuario { [Key] public int UsuarioID { get; set; } public int PessoaID { get; set; } [Required(ErrorMessage = "Campo 'Nome' é obrigatório")] [Display(Name = "Login")] public string Login { get; set; } [Required(ErrorMessage = "Campo 'E-mail' é obrigatório")] [Display(Name = "E-mail")] [DataType(DataType.EmailAddress)] [ERP.Helpers.Validacoes.Email] [NotMapped] public string Email { get; set; } [Required(ErrorMessage = "Campo 'Confirme E-mail' é obrigatório")] [Display(Name = "Confirme E-mail")] [Compare("Email", ErrorMessage = "O 'e-mail' e a 'confirme o e-mail' não estão iguais")] [DataType(DataType.EmailAddress)] [ERP.Helpers.Validacoes.Email] [NotMapped] public string ConfirmeEmail { get; set; } [Required(ErrorMessage = "Campo 'Nome' é obrigatório")] [Display(Name = "Nome")] public string Nome { get; set; } [Required(ErrorMessage = "Campo 'Senha' é obrigatório")] [Display(Name = "Senha")] [StringLength(50, ErrorMessage = "A {0} deve ter {2} caracteres no mínimo", MinimumLength = 6)] [DataType(DataType.Password)] public string Senha { get; set; } [Required(ErrorMessage = "Campo 'Confirme a senha' é obrigatório")] [Display(Name = "Confirme a senha")] [Compare("Senha", ErrorMessage = "A 'senha' e a 'confirme a senha' não estão iguais")] [DataType(DataType.Password)] [NotMapped] public string ConfirmeSenha { get; set; } public string Chave { get; set; } public Nullable<DateTime> DtAtivacao { get; set; } public string Gestor { get; set; } public string GestorVisao { get; set; } public string UsuarioExtra { get; set; } [Required(ErrorMessage = "Campo 'Tipo de pessoa' é obrigatório")] [Display(Name = "Tipo de pessoa")] [NotMapped] public int TipoPessoaID { get; set; } [Required(ErrorMessage = "Campo 'Sexo' é obrigatório")] [Display(Name = "Sexo")] [ERP.Helpers.Validacoes.CompareValuesAttribute("TipoPessoaID")] [NotMapped] public int SexoID { get; set; } public int EmpresaID { get; set; } public string Fixo { get; set; } public string Status { get; set; } public string Apagado { get; set; } public Nullable<DateTime> DtApagado { get; set; } public int UsuCad { get; set; } public DateTime DtCad { get; set; } public int UsuAlt { get; set; } public DateTime DtAlt { get; set; } public int UsuUltAlt { get; set; } public DateTime DtUltAlt { get; set; } }
Abs
Marlon Tiedt
www.sesmt.com.br
Respostas
-
Oi Marlon,
Sobre previsão para resolução deste problema é difícil falar.
Neste caso, o recomendado é criar outro DbContext, que mapeie outra classe (se vc estivesse utilizando Fluent API não precisaria de outra classe) com apenas os campos que quer atualizar para essa tabela.
[]s!
Fernando Henrique Inocêncio Borba Ferreira
Microsoft MVP - Data Platform Development
while(alive){ this.WriteCode(); }
Blog: http://ferhenriquef.com/
Twitter: @ferhenrique
Entity Framework - Brasil: https://www.facebook.com/EntityFrameworkBrasil- Marcado como Resposta Marlon Tiedt sexta-feira, 5 de outubro de 2012 11:24
Todas as Respostas
-
Olá Marlon,
Neste caso vc pode tentar indicar para o EF que vc quer apenas fazer o UPDATE de um único campo.
Veja o exemplo abaixo:
public void ChangePassword(int userId, string password) { var user = new User() { Id = userId, Password = password }; using (var db = new MyEfContextName()) { db.Users.Attach(user); db.Entry(user).Property(x => x.Password).IsModified = true; db.SaveChanges(); } }
A propriedade Password será a única modificada.
Veja se isso atende o seu problema.
[]s!
Fernando Henrique Inocêncio Borba Ferreira
Microsoft MVP - Data Platform Development
while(alive){ this.WriteCode(); }
Blog: http://ferhenriquef.com/
Twitter: @ferhenrique
Entity Framework - Brasil: https://www.facebook.com/EntityFrameworkBrasil -
Olá Fernando,
o sistema ainda reclama que está faltando campos obrigatórios...
var user = new Usuario() { UsuarioID = dados.UsuarioID, DtAtivacao = DateTime.Now }; db.Usuario.Attach(user); db.Entry(user).Property(x => x.DtAtivacao).IsModified = true; db.SaveChanges();
Abs
Marlon Tiedt
www.sesmt.com.br- Editado Marlon Tiedt quarta-feira, 3 de outubro de 2012 13:39
-
Putz...
Isso é muito chato... outro dia li um e-mail de alguns Data Insiders reclamando justamente disso... mesmo marcando só algumas propriedades para serem salvas na base de dados, a validação acontecia para todas as propriedades.
Marlon, neste caso, acredito que o jeito mais rápido e fácil de resolver esta questão seja criar uma procedure que faça essa atualização e fazer o EF executá-la...
Acredito que este seja um bug que será corrigido nas próximas versões.
[]s!
Fernando Henrique Inocêncio Borba Ferreira
Microsoft MVP - Data Platform Development
while(alive){ this.WriteCode(); }
Blog: http://ferhenriquef.com/
Twitter: @ferhenrique
Entity Framework - Brasil: https://www.facebook.com/EntityFrameworkBrasil -
-
Oi Marlon,
Sobre previsão para resolução deste problema é difícil falar.
Neste caso, o recomendado é criar outro DbContext, que mapeie outra classe (se vc estivesse utilizando Fluent API não precisaria de outra classe) com apenas os campos que quer atualizar para essa tabela.
[]s!
Fernando Henrique Inocêncio Borba Ferreira
Microsoft MVP - Data Platform Development
while(alive){ this.WriteCode(); }
Blog: http://ferhenriquef.com/
Twitter: @ferhenrique
Entity Framework - Brasil: https://www.facebook.com/EntityFrameworkBrasil- Marcado como Resposta Marlon Tiedt sexta-feira, 5 de outubro de 2012 11:24
-
-
Olá Fernando,
pensando em ter 2 DBContext, esta forma abaixo está correta, ou preciso fazer 2 strings de conexão?
public class ERPContext : DbContext { public DbSet<UsuarioAtivacao> UsuarioAtivacao { get; set; } public ERPContext() { Database.SetInitializer<ERPCodeFirstContext>(null); } protected override void OnModelCreating(DbModelBuilder modelBuilder) { var _DBOwner = "dbo"; modelBuilder.Entity<UsuarioAtivacao>().ToTable("Usuario", schemaName: _DBOwner); } }
DBContext original:
public class ERPCodeFirstContext : DbContext { public DbSet<Usuario> Usuario { get; set; } public ERPCodeFirstContext() { Database.SetInitializer<ERPCodeFirstContext>(null); } protected override void OnModelCreating(DbModelBuilder modelBuilder) { var _DBOwner = "dbo"; modelBuilder.Entity<Usuario>().ToTable("Usuario", schemaName: _DBOwner); } }
WebConfig:
<add name="ERPCodeFirstContext" connectionString="Data Source=E020\SQLExpress;Initial Catalog=ERP;User ID=ERP; Password=testes" providerName="System.Data.SqlClient" />
AbsMarlon Tiedt
www.sesmt.com.br -
Oi Marlon,
Pode ter uma única string de conexão ;)
[]s!
Fernando Henrique Inocêncio Borba Ferreira
Microsoft MVP - Data Platform Development
while(alive){ this.WriteCode(); }
Blog: http://ferhenriquef.com/
Twitter: @ferhenrique
Entity Framework - Brasil: https://www.facebook.com/EntityFrameworkBrasil