MVC 3 EF 4.1 dbContext - Excluindo um objeto de dados um para muitos com uma relação de chave estrangeira não anulável
Estou usando MVC 3, EF 4.1 e dbContext. Preciso saber como excluir uma entidade na relação de um para muitos com uma chave estrangeira não anulável.
Quando removo a entidade filha e executo SaveChanges, recebo o erro:
A operação falhou: o relacionamento não pôde ser alterado porque uma ou mais propriedades da chave estrangeira não podem ser anuladas. Quando uma alteração é feita em um relacionamento, a propriedade de chave estrangeira relacionada é definida como um valor nulo. Se a chave estrangeira não suportar valores nulos, um novo relacionamento deverá ser definido, a propriedade da chave estrangeira deverá receber outro valor não nulo ou o objeto não relacionado deverá ser excluído.
De outras postagens, eu entendo que o uso de Remove (entity) marca a entidade para exclusão. Durante SaveChanges, EF define a chave estrangeira como Nulo e ocorre o erro acim
Encontrei algumas postagens que usam DeleteObject na entidade filha, em vez de Remover; no entanto, a abordagem DeleteObject parece ter sido descartada devido à adição ao dbContext e DbSe
Encontrei postagens que sugerem modificar a relação de chave estrangeira do EDMX para que seja anulável. A modificação do EDMX é boa, mas sempre que um Modelo de Atualização para o Banco de Dados é feito, essas alterações são desativadas e devem ser reaplicadas. Não é o ideal.
Outra publicação sugeriu a criação de uma entidade proxy com as relações de chave estrangeira definidas como Nullable, mas não entendo essa abordagem. Parece sofrer do mesmo problema que a modificação do EDMX, pois o contexto é atualizado automaticamente quando as alterações no EDMX são salva
Meu modelo simplificado é:
public partial class User
{
public User()
{
this.UserContacts = new HashSet<UserContact>();
}
public long userId { get; set; }
public string userEmail { get; set; }
public string userPassword { get; set; }
public string userFirstName { get; set; }
public string userLastName { get; set; }
. . .
public virtual Country Country { get; set; }
public virtual State State { get; set; }
public virtual ICollection<UserContact> UserContacts { get; set; }
}
}
public partial class UserContact
{
public long userContactId { get; set; }
public long userContactUserId { get; set; }
public long userContactTypeId { get; set; }
public string userContactData { get; set; }
public virtual ContactType ContactType { get; set; }
public virtual User User { get; set; }
}
The userContactUserId e userContactTypeId são chaves estrangeiras necessárias.
No contêiner dbContext, Users e UserContact são DbSe
Tenho um ViewModel para o usuário e um ViewModel para UserContact da seguinte forma
public class UserContactViewModel
{
[HiddenInput]
public long UserContactId { get; set; }
[HiddenInput]
public long UserContactUserId { get; set; }
[Display(Name = "Contact")]
[Required]
public string ContactData { get; set; }
[Required]
public long ContactType { get; set; }
[HiddenInput]
public bool isDeleted { get; set; }
}
public class MyProfileViewModel
{
[HiddenInput]
public long UserId { get; set; }
[Required]
[Display(Name = "First Name")]
[StringLength(100)]
public string FirstName { get; set; }
[Required]
[StringLength(100)]
[Display(Name = "Last Name")]
public string LastName { get; set; }
....
public IEnumerable<UserContactViewModel> Contacts { get; set; }
}
Ao salvar as alterações no perfil do usuário, percorro a lista de entidades UserContactViewModel para determinar quais foram adicionadas, modificadas ou excluída
foreach (var c in model.Contacts)
{
UserContact uc = usr.UserContacts.Single(con => con.userContactId == c.UserContactId);
if (uc != null)
{
if (c.isDeleted == true) // Deleted UserContact
{
ctx.UserContacts.Remove(uc); // Remove doesn't work
}
else // Modified UserContact
{
uc.userContactData = c.ContactData;
uc.userContactTypeId = c.ContactType;
ctx.Entry(uc).State = EntityState.Modified;
}
}
else // New UserContact
{
usr.UserContacts.Add(new UserContact { userContactUserId = model.UserId, userContactData = c.ContactData, userContactTypeId = c.ContactType });
}
}
Eu apreciaria qualquer ajuda.