从更新中排除属性而不是更新整个对象
Excluding properties from update instead of updating whole object
我正在使用 ASP.NET 带有代码优先 Entity Framework 6 和 MVC 5 的样板。
为了更新实体,我正在使用 UpdateAsync
。
如何在执行更新之前从实体中排除某些属性?
我应该使用什么功能,它是否已在 ASP.NET 样板中实现?
我在 Entity Framework 6 中实现了如下:
public virtual TEntity UpdateWithExcludeProperities(TEntity entity,string [] properities)
{
if (entity == null)
throw new ArgumentException("Paramter cannot be null", "entity");
var existedEntity = SelectFromContext(entity.ID);
if (existedEntity == null)
throw new ObjectNotFoundException("Record is not found!");
_context.Entry(existedEntity).CurrentValues.SetValues(entity);
foreach (var name in properities)
{
_context.Entry(existedEntity).Property(name).IsModified = false;
}
_context.SaveChanges();
return existedEntity;
}
public virtual TEntity SelectFromContext(Guid id)
{
TEntity entity;
entity = DbSet<TEntity>().SingleOrDefault(e => e.ID == id);
return entity;
}
但是有没有可能在 ASP.NET 样板中实现此代码?
你走错了路!
使用指定字段更新实体非常简单。
1- 创建一个 DTO。
2-配置映射
3- 获取实体并将 DTO 映射到实体。
查看我的示例。在这个例子中 Student
实体有 3 个属性。在 StudentAppService
UpdateOnlyNameOfStudent()
方法中,我们只更新 Student 的 Name
字段。请注意,我什至没有 运行 _studentRepository.Update(student)
因为 AspNet Boilerplate 在方法结束时提交更改(参见 automatic save change)
StudentDto.cs
[AutoMapFrom(typeof(Student))]
public class StudentDto: EntityDto<long>
{
public string Name { get; set; }
}
Student.cs
public class Student: Entity
{
public string Name { get; set; }
public int SchoolNumber { get; set; }
public DateTime RegisterDate { get; set; }
}
StudentAppService.cs
public class StudentAppService : IStudentAppService
{
private readonly IRepository<Student> _studentRepository;
public RoleAppService(IRepository<Student> studentRepository)
{
_studentRepository = studentRepository;
}
public override async void UpdateOnlyNameOfStudent(StudentDto input)
{
var student = _studentRepository.Get(input.Id);
ObjectMapper.Map(input, student);
}
/*
public override async void UpdateOnlyNameOfStudent_Alternative(StudentDto input)
{
var student = _studentRepository.Get(input.Id);
student.Name = input.Name;
}
*/
}
AspNet Boilerplate 使用 AutoMapper 来映射对象。参见 Object To Object Mapping
我能够在 ASP.NET 样板中通过仅直接使用 Ef 核心 LINQ 查询来做到这一点
public virtual TEntity SelectFromContext(TPrimaryKey id)
{
TEntity entity;
entity = Repository.GetDbContext().Set<TEntity>().SingleOrDefault(e => e.Id.Equals(id));
return entity;
}
public virtual async Task<TEntity> UpdateWithExclude(TEntity entity, string[] properities)
{
if (entity == null)
throw new ArgumentException("Paramter cannot be null", "entity");
var existedEntity = SelectFromContext(entity.Id);
if (existedEntity == null)
throw new ObjectNotFoundException("Record is not found!");
var currentValues = Repository.GetDbContext().Entry(existedEntity).CurrentValues;
foreach (var properteyName in currentValues.PropertyNames)//make default false value for all
{
var y = Repository.GetDbContext().Entry(existedEntity).Property(properteyName);
if (!properities.Contains(y.Name))
Repository.GetDbContext().Entry(existedEntity).Property(properteyName).IsModified = false;
}
Repository.GetDbContext().Entry(existedEntity).CurrentValues.SetValues(entity);
Repository.GetDbContext().SaveChanges();
var UpdatedEntity = SelectFromContext(entity.Id);
return await Task.FromResult(UpdatedEntity);
}
我正在使用 ASP.NET 带有代码优先 Entity Framework 6 和 MVC 5 的样板。
为了更新实体,我正在使用 UpdateAsync
。
如何在执行更新之前从实体中排除某些属性?
我应该使用什么功能,它是否已在 ASP.NET 样板中实现?
我在 Entity Framework 6 中实现了如下:
public virtual TEntity UpdateWithExcludeProperities(TEntity entity,string [] properities)
{
if (entity == null)
throw new ArgumentException("Paramter cannot be null", "entity");
var existedEntity = SelectFromContext(entity.ID);
if (existedEntity == null)
throw new ObjectNotFoundException("Record is not found!");
_context.Entry(existedEntity).CurrentValues.SetValues(entity);
foreach (var name in properities)
{
_context.Entry(existedEntity).Property(name).IsModified = false;
}
_context.SaveChanges();
return existedEntity;
}
public virtual TEntity SelectFromContext(Guid id)
{
TEntity entity;
entity = DbSet<TEntity>().SingleOrDefault(e => e.ID == id);
return entity;
}
但是有没有可能在 ASP.NET 样板中实现此代码?
你走错了路! 使用指定字段更新实体非常简单。
1- 创建一个 DTO。
2-配置映射
3- 获取实体并将 DTO 映射到实体。
查看我的示例。在这个例子中 Student
实体有 3 个属性。在 StudentAppService
UpdateOnlyNameOfStudent()
方法中,我们只更新 Student 的 Name
字段。请注意,我什至没有 运行 _studentRepository.Update(student)
因为 AspNet Boilerplate 在方法结束时提交更改(参见 automatic save change)
StudentDto.cs
[AutoMapFrom(typeof(Student))]
public class StudentDto: EntityDto<long>
{
public string Name { get; set; }
}
Student.cs
public class Student: Entity
{
public string Name { get; set; }
public int SchoolNumber { get; set; }
public DateTime RegisterDate { get; set; }
}
StudentAppService.cs
public class StudentAppService : IStudentAppService
{
private readonly IRepository<Student> _studentRepository;
public RoleAppService(IRepository<Student> studentRepository)
{
_studentRepository = studentRepository;
}
public override async void UpdateOnlyNameOfStudent(StudentDto input)
{
var student = _studentRepository.Get(input.Id);
ObjectMapper.Map(input, student);
}
/*
public override async void UpdateOnlyNameOfStudent_Alternative(StudentDto input)
{
var student = _studentRepository.Get(input.Id);
student.Name = input.Name;
}
*/
}
AspNet Boilerplate 使用 AutoMapper 来映射对象。参见 Object To Object Mapping
我能够在 ASP.NET 样板中通过仅直接使用 Ef 核心 LINQ 查询来做到这一点
public virtual TEntity SelectFromContext(TPrimaryKey id)
{
TEntity entity;
entity = Repository.GetDbContext().Set<TEntity>().SingleOrDefault(e => e.Id.Equals(id));
return entity;
}
public virtual async Task<TEntity> UpdateWithExclude(TEntity entity, string[] properities)
{
if (entity == null)
throw new ArgumentException("Paramter cannot be null", "entity");
var existedEntity = SelectFromContext(entity.Id);
if (existedEntity == null)
throw new ObjectNotFoundException("Record is not found!");
var currentValues = Repository.GetDbContext().Entry(existedEntity).CurrentValues;
foreach (var properteyName in currentValues.PropertyNames)//make default false value for all
{
var y = Repository.GetDbContext().Entry(existedEntity).Property(properteyName);
if (!properities.Contains(y.Name))
Repository.GetDbContext().Entry(existedEntity).Property(properteyName).IsModified = false;
}
Repository.GetDbContext().Entry(existedEntity).CurrentValues.SetValues(entity);
Repository.GetDbContext().SaveChanges();
var UpdatedEntity = SelectFromContext(entity.Id);
return await Task.FromResult(UpdatedEntity);
}