tmn*_*ngu 5 c# entity-framework-core .net-core
我已经经历过这里提供的一些解决方案,就像这样。基本上我有一个User具有很多属性的类。
public class Users
{
[Key]
public Guid Id { get; set; }
[MaxLength(200)]
public string Username { get; set; }
public bool Enabled { get; set; }
public string Name { get; set; }
//...Many more properties
}
Run Code Online (Sandbox Code Playgroud)
以及UpdateUser()更新用户的方法。我的问题是该方法很长并且看起来不干净,因为正在更新许多属性。
public async Task<UpdateUserResponse> UpdateUser(UpdateUserRequest userRequest)
{
var user = await _userRepository.GetByIdAsync(userRequest.Id);
if (user == null)
throw new HttpException(HttpStatusCode.BadRequest, $"User does not exist");
user.EmailAddress = userRequest.EmailAddress;
user.Enabled = userRequest.Enabled;
user.Name = userRequest.Name;
user.SurName = userRequest.SurName;
//...many more properties which make this method to be long
// I attempted to do something like this which gave the error
// var usrObj = JsonConvert.DeserializeObject<Users>(JsonConvert.SerializeObject(userRequest));
// var res = await _userRepository.UpdateAsync(usrObj);
context.Entry(user).State = EntityState.Modified;
var result = await context.SaveChangesAsync();
//......
return response;
}
Run Code Online (Sandbox Code Playgroud)
我尝试将userRequest对象反序列化为类型User,但在该UpdateAsync()方法中,Entity Framework Core 抱怨以下消息,这是有道理的:
无法跟踪实体类型“Users”的实例,因为已跟踪具有相同键值 {'Id'} 的另一个实例。
我正在寻找一种更清洁的方法来做到这一点。
Iva*_*oev 12
首先,当使用加载/修改/保存模式时,不要调用
context.Entry(user).State = EntityState.Modified;
Run Code Online (Sandbox Code Playgroud)
或者
context.Update(user);
Run Code Online (Sandbox Code Playgroud)
这些强制将实体的所有属性更新到数据库中,并且适用于当您没有从数据库中新鲜加载(并由上下文更改跟踪器跟踪)实体实例时断开连接的实体场景。
当您拥有它时(与相关代码一样),您所需要的只是设置一些属性,然后 EF Core 更改跟踪器将自动确定要在数据库中更新哪些属性(如果所有属性都可能根本不会发出更新命令)值与原始值相同)。
话虽如此,具体问题是如何在不编写大量代码的情况下设置感兴趣的目标属性。EF Core 提供了开箱即用的EntityEntry.CurrentValues属性和方法SetValues,只要属性名称和类型匹配,它就与实体类实例一起接受字典或任何对象。类似于 AutoMapper 默认映射的东西。但请注意,这仅适用于原始(数据)属性,导航属性需要手动更新。
所以有问题的代码可以简化为
public async Task<UpdateUserResponse> UpdateUser(UpdateUserRequest userRequest)
{
var user = await _userRepository.GetByIdAsync(userRequest.Id);
if (user == null)
throw new HttpException(HttpStatusCode.BadRequest, $"User does not exist");
// Assuming GetByIdAsync method returns tracked entity instances
// If not, you'd need to modify it or use another one which does that
// The next call is all you need to update matching properties
context.Entry(user).CurrentValues.SetValues(userRequest);
var result = await context.SaveChangesAsync();
//......
return response;
}
Run Code Online (Sandbox Code Playgroud)
如果您需要更大的灵活性(具有不匹配的源属性,或者不想应用所有源属性,或者想要处理导航属性等),您最好使用一些第三方库,例如 AutoMapper。
| 归档时间: |
|
| 查看次数: |
8287 次 |
| 最近记录: |