加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc – MVC中具有存储库/ DTO模式的实体的部分更新(准备

发布时间:2020-12-16 09:38:40 所属栏目:asp.Net 来源:网络整理
导读:我已经构建了我的域模型层,我的存储库层,现在我正在处理我的DTO层以供webApi项目使用.我正在实现更新服务方法,我想知道部分更新.这是我的DTO课程: public class FullPersonDto { public FullPersonDto() { Friends = new ListPerson(); } public FullPerson
我已经构建了我的域模型层,我的存储库层,现在我正在处理我的DTO层以供webApi项目使用.我正在实现更新服务方法,我想知道部分更新.这是我的DTO课程:

public class FullPersonDto
    {
        public FullPersonDto()
        {
            Friends = new List<Person>();
        }

        public FullPersonDto(Person person)
        {
            PersonId = person.PersonId;
            DateCreated = person.DateCreated;
            Details = person.Details;
            Friends = new List<Person>();
            foreach (Person friend in person.Friends)
            {
                Friends.Add(new PersonDto(friend));
            }
        }

        [Key]
        public int PersonId { get; set; }

        [Required]
        public virtual DateTime DateCreated { get; set; }

        public virtual string Details { get; set; }

        public List<Person> Friends { get; set; } 

        public Person ToEntity()
        {
            var person = new Person
            {
                PersonId = PersonId,DateCreated = (DateTime) DateCreated,Details = Details,Friends = new List<Person>()
            };
            foreach (PersonDto friend in Friends)
            {
                person.Friends.Add(friend.ToEntity());
            }
            return person;
        }
    }

这是我的Repository中的Update方法:

public Person UpdatePerson(Person person)
        {
            var entry = _db.Entry(person);
            if (entry.State == EntityState.Detached)
            {
                var dbSet = _db.Set<Person>();
                Person attachedPerson = dbSet.Find(person.PersonId);
                if (attachedPerson != null)
                {
                    var attachedEntry = _db.Entry(attachedPerson);
                    attachedEntry.CurrentValues.SetValues(person);  // what if values are null,like ID,or DateCreated?
                }
                else
                {
                    entry.State = EntityState.Modified;
                }

            }
            SaveChanges();
            return person;
        }

我的问题是:如果我只需要通过我的webAPI更新一个人的详细信息怎么办?是使用SetValues构造整个PersonDto和更新整个对象的约定,还是有任何方法可以指定我只需要更新单个字段,这样我就不必通过线路发送大量数据(我真的不需要)?

如果可以进行部分更新,何时更新整个实体是否有用?即使我必须更新5/7属性,它也要求我发送2/7的旧数据来重写,以便SetValues不会从我的DTO中将空值写入我的字段.

这里的任何帮助都会很棒……对这些东西来说是全新的,并试图正确地学习一切.谢谢.

解决方法

我采取了类似的方法来进行优化,并且在连接时我遇到了与null值相同的问题(不仅仅是null,你也会遇到布尔问题).这就是我想出来的:

public static void Update<T>(this DbContext context,IDTO dto)
        where T : class,IEntity
    {
        T TEntity = context.Set<T>().Local.FirstOrDefault(x => x.Id == dto.Id);
        if (TEntity == null)
        {
            TEntity = context.Set<T>().Create();
            TEntity.Id = dto.Id;
            context.Set<T>().Attach(TEntity);
        }
        context.Entry(TEntity).CurrentValues.SetValues(dto);
        var attribute = dto.GetAttribute<EnsureUpdatedAttribute>();
        if (attribute != null)
        {
            foreach (var property in attribute.Properties)
                context.Entry(TEntity).Property(property).IsModified = true;
        }
    }

这是DbContext的扩展方法.以下是IDTO和IEntity的接口:

public interface IDTO
{
    int Id { get; set; }
}

public interface IEntity
{
    int Id { get; set; }

    Nullable<DateTime> Modified { get; set; }
    Nullable<DateTime> Created { get; set; }
}

我正在使用我的自定义EnsureUpdatedAttribute来注释应始终更新哪些属性(以处理未跟踪的空值/默认值):

public class EnsureUpdatedAttribute : Attribute
{
    public IEnumerable<string> Properties { get; private set; }

    public EnsureUpdatedAttribute(params string[] properties)
    {
        Properties = properties.AsEnumerable();
    }
}

这是一个用法示例:

public class Sample : IEntity
{
    public int Id { get; set; }

    public string Name { get; set; }

    public bool Active { get; set; }

    public Nullable<DateTime> Modified { get; set; }
    public Nullable<DateTime> Created { get; set; }
}


[EnsureUpdated("Active")] /// requirement for entity framework change tracking,read about stub entities
public class SampleDTO : IDTO
{
    public int Id { get; set; }

    [Required]
    public string Name { get; set; }

    [JsonIgnore] /// How to exclude property from going on the wire / ignored for serialization
    public bool Active { get; set; }
}

    [HttpPost]
    public HttpResponseMessage SaveSample(SampleDTO dto)
    {
        dto.Active = true;
        _ctx.AddModel<Sample>(dto);
        _ctx.SaveChanges();
        return NoContent();
    }

return NoContent()只是返回204(NoContent)的扩展名.

希望这可以帮助.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读