ASP.NET如何在不手动设置每个记录的情况下更新记录属性?
ASP.NET How to update a record without manually setting each property?
如果我有一个更改了 100 个属性的对象怎么办?
这对编码来说会很糟糕,并且容易丢失一些属性。
是否有与手动更新记录不同的方式?
ApplicationUser CurrentUser = db.Users.FirstOrDefault(x => x.Id == model.Id);
CurrentUser.FirstName = model.FirstName;
CurrentUser.LastName = model.LastName;
CurrentUser.IsRSM = model.IsRSM;
CurrentUser.PhoneNumber = model.PhoneNumber;
CurrentUser.Email = model.Email;
CurrentUser.UserName = model.Email;
CurrentUser.Region = model.Region;
CurrentUser.Active = model.Active;
db.Entry(CurrentUser).State = System.Data.Entity.EntityState.Modified;
db.SaveChanges();
根据评论,您可以通过以下两种方式以编程方式执行此操作:
反思
var CurrentUser = db.Users.FirstOrDefault(x => x.Id == model.Id);
PropertyInfo[] sourceProps = model.GetType()
.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty);
PropertyInfo[] targetProps = CurrentUser.GetType()
.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty);
foreach (var prop in sourceProps)
{
var targetProp = targetProps.FirstOrDefault(x => x.Name == prop.Name);
if (targetProp != null)
targetProp.SetValue(CurrentUser, prop.GetValue(model));
}
db.Entry(CurrentUser).State = EntityState.Modified;
db.SaveChanges();
AutoMapper
首先在应用程序启动时创建地图:
cfg.CreateMap<ApplicationUserViewModel, ApplicationUser>();
然后执行映射:
_mapper.Map<ApplicationUserViewModel, ApplicationUser>(model, CurrentUser)
还有第三种方法
- 创建一个您手动映射属性的映射方法。 (没有 "expensive" 反映)
- 为该映射方法创建单元测试,验证所有属性设置是否正确且没有遗漏。
通过测试,您将始终确保没有属性遗漏或设置为用于它们的错误值。
通过测试,您可以重构您的方法,使用 Automapper 的反射,您将始终 "check" 正确映射属性。
你可以这样做
ApplicationUser CurrentUser = db.Users.FirstOrDefault(x => x.Id == model.Id);
Context.Entry(CurrentUser).CurrentValues.SetValues(ObjectBeingPassed);
在您的方法中,您需要期待来自您的 post 的记录,其中将包含每个 属性 (ObjectBeingPassed).
如果我有一个更改了 100 个属性的对象怎么办?
这对编码来说会很糟糕,并且容易丢失一些属性。
是否有与手动更新记录不同的方式?
ApplicationUser CurrentUser = db.Users.FirstOrDefault(x => x.Id == model.Id);
CurrentUser.FirstName = model.FirstName;
CurrentUser.LastName = model.LastName;
CurrentUser.IsRSM = model.IsRSM;
CurrentUser.PhoneNumber = model.PhoneNumber;
CurrentUser.Email = model.Email;
CurrentUser.UserName = model.Email;
CurrentUser.Region = model.Region;
CurrentUser.Active = model.Active;
db.Entry(CurrentUser).State = System.Data.Entity.EntityState.Modified;
db.SaveChanges();
根据评论,您可以通过以下两种方式以编程方式执行此操作:
反思
var CurrentUser = db.Users.FirstOrDefault(x => x.Id == model.Id);
PropertyInfo[] sourceProps = model.GetType()
.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty);
PropertyInfo[] targetProps = CurrentUser.GetType()
.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty);
foreach (var prop in sourceProps)
{
var targetProp = targetProps.FirstOrDefault(x => x.Name == prop.Name);
if (targetProp != null)
targetProp.SetValue(CurrentUser, prop.GetValue(model));
}
db.Entry(CurrentUser).State = EntityState.Modified;
db.SaveChanges();
AutoMapper
首先在应用程序启动时创建地图:
cfg.CreateMap<ApplicationUserViewModel, ApplicationUser>();
然后执行映射:
_mapper.Map<ApplicationUserViewModel, ApplicationUser>(model, CurrentUser)
还有第三种方法
- 创建一个您手动映射属性的映射方法。 (没有 "expensive" 反映)
- 为该映射方法创建单元测试,验证所有属性设置是否正确且没有遗漏。
通过测试,您将始终确保没有属性遗漏或设置为用于它们的错误值。
通过测试,您可以重构您的方法,使用 Automapper 的反射,您将始终 "check" 正确映射属性。
你可以这样做
ApplicationUser CurrentUser = db.Users.FirstOrDefault(x => x.Id == model.Id);
Context.Entry(CurrentUser).CurrentValues.SetValues(ObjectBeingPassed);
在您的方法中,您需要期待来自您的 post 的记录,其中将包含每个 属性 (ObjectBeingPassed).