[英]How Working With Entity Framework Detached Objects?
你好社区我一直在努力解决这个问题很长一段时间,我正在使用blazor webassembly,do.net core和EntityFramework,我想更新我个人object的数据,这个object包含相关数据,neighborhood,municipality和state,如果我只更新这个人 object 如果它更新它会很好地工作,但是如果在查询中我包含带有 inlcude 的导航属性它不再更新导航属性
错误:
System.InvalidOperationException:无法跟踪实体类型“Status”的实例,因为已跟踪另一个具有与 {'StatusId'} 相同键值的实例。 附加现有实体时,确保只附加一个具有给定键值的实体实例。
我看到已经有类似的问题,但事实是我找不到解决问题的方法。
我尝试了以下博客所说的内容:
但效果不太好
[HttpPut]
public async Task<ActionResult> Put(Persona persona)
{
var user = await _userManager.GetUserAsync(HttpContext.User);
var oldpersona = await context.Personas.FindAsync(persona.PersonaId);
context.Entry(oldpersona).CurrentValues.SetValues(persona);
context.Entry(oldpersona).CurrentValues.SetValues(persona.Colonia);
context.Entry(oldpersona).CurrentValues.SetValues(persona.Municipio);
context.Entry(oldpersona).CurrentValues.SetValues(persona.Estado);
await context.SaveChangesAsync(user.Id);
return NoContent();
}
我读过我可以使用.AsNoTracking() 来不跟踪实体,但如果我需要跟踪它们,我将编辑它们。
这是我在 controller 人中的代码:
[HttpGet("{id}")]
public async Task<ActionResult<Persona>> Get(int id)
{
var persona = await context.Personas.Where(x => x.PersonaId == id)
.Include(x => x.Colonia)
.Include(x => x.Municipio)
.Include(x => x.Estado)
.FirstOrDefaultAsync();
if (persona == null) { return NotFound(); }
return persona;
}
[HttpPut]
public async Task<ActionResult> Put(Persona persona)
{
context.Attach(persona).State = EntityState.Modified;
await context.SaveChangesAsync();
return NoContent();
}
这是我的相关课程:
public class Persona
{
[Key]
public int PersonaId { get; set; }
public string Nombre { get; set; }
public string Ap_Paterno { get; set; }
public string Ap_Materno { get; set; }
public Sexo Sexo { get; set; }
public DateTime? FechadeNacimiento {get; set;}
public int Edad
{
get
{
DateTime now = DateTime.Today;
int Edad = DateTime.Today.Year - FechadeNacimiento.Value.Year;
if (DateTime.Today < FechadeNacimiento.Value.AddYears(Edad))
return --Edad;
else
return Edad;
}
}
public string Email { get; set; }
public string Telefono { get; set; }
public string Celular { get; set; }
[StringLength(12)]
public string Nss { get; set; }
[StringLength(18)]
public string Curp { get; set; }
[StringLength(13)]
public string Rfc { get; set; }
public string Observaciones { get; set; }
public string Calle { get; set; }
public string Num_Ext { get; set; }
public string Num_Int { get; set; }
public int CodigoPostal { get; set; }
public DateTime? FechaRegistro { get; set; }
public bool Activo { get; set; }
//propiedades de navegacion
public int? ColoniaId { get; set; }
public virtual Colonia Colonia { get; set; }
public int? MunicipioId { get; set; }
public virtual Municipio Municipio { get; set; }
public int? EstadoId { get; set; }
public virtual Estado Estado { get; set; }
}
public enum Sexo
{
Masculino,
Femenino,
Indefinido
}
public class Estado
{
[Key]
public int EstadoId { get; set; }
[Required(ErrorMessage = "El campo {0} es requerido")]
public string Nombre { get; set; }
public DateTime? FechaRegistro { get; set; }
public bool Activo { get; set; }/
//propiedades de navegacion
public int ZonaId{ get; set; }
public virtual Zona Zona { get; set; }
}
public class Municipio
{
[Key]
public int MunicipioId { get; set; }
[Required(ErrorMessage = "El campo {0} es requerido")]
public string Nombre { get; set; }
public DateTime? FechaRegistro { get; set; }
public bool Activo { get; set; }
//propiedades de navegacion
public int EstadoId { get; set; }
public virtual Estado Estado { get; set; }
}
public class Colonia
{
[Key]
public int ColoniaId { get; set; }
[Required(ErrorMessage = "El campo {0} es requerido")]
public int CodigoPostal { get; set; }
public Asentamiento Asentamiento { get; set; }
[Required(ErrorMessage = "El campo {0} es requerido")]
public string NombreColonia { get; set; }
public DateTime? FechaRegistro { get; set; }
public bool Activo { get; set; }
//propiedades de navegacion
public int MunicipioId { get; set; }
public virtual Municipio Municipio { get; set; }
public int EstadoId { get; set; }
public virtual Estado Estado { get; set; }
}
public enum Asentamiento
{
Colonia,
Fraccionamiento,
Condominio,
[Display(Name = "Unidad habitacional")]
Unidadhabitacional,
Barrio,
Equipamiento,
[Display(Name = "Zona comercial")]
Zonacomercial,
Rancho,
Rancheria,
[Display(Name = "Parque industrial")]
Parqueindustrial,
Granja,
Pueblo,
Ejido,
[Display(Name = " Zona federal")]
Zonafederal,
Aeropuerto,
Hacienda,
Paraje
}
我想问题是,当我执行包含时,在市政当局内部它带来了 state 并且在殖民地内部带来了 state 和市政当局,这就是为什么 EF 不止一次跟踪这些实体,但我该如何解决呢?
var person = await context.People.Where(x => x.PersonId == id).Include(x => x.Colony).Include(x => x.Municipality).包括(x => x.Status) .FirstOrDefaultAsync();
没有办法做这样的事情:
var person = await context.People.Where(x => x.PersonId == id).Include(x => x.Colony).包括(x => x.Municipality).ThenInclude(x=>x.State) .AsNoTracking().Include(x => x.Status).FirstOrDefaultAsync(); 如果(人 == null){ 返回 NotFound(); } 返回人;
因此在市政当局中,它不会跟踪其中的实体,在这种情况下为 state,并且不会干扰我已经拥有的 state 包含
编辑具有导航属性的实体的最佳方式是什么??
我还看到他们使用 Detach,但我真的不知道如何在我的代码中使用它。
Entry<Persona>(persona).State = EntityState.Detached;
试试这个
[HttpPut]
public async Task<ActionResult> Put(Persona persona)
{
var existedPersona = await context.Personas.Where(x => x.PersonaId == persona.PersonaId)
.FirstOrDefaultAsync();
if (existedPersona == null) { return NotFound(); }
context.Entry(existedPersona).CurrentValues.SetValues(persona);
await context.SaveChangesAsync();
return NoContent();
}
如果您在导航属性中也有一些更新,则包括它们
var existedPersona = await context.Personas.Where(x => x.PersonaId == id)
.Include(x => x.Colonia)
.Include(x => x.Municipio)
.Include(x => x.Estado)
.FirstOrDefaultAsync();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.