3

エンティティ フレームワークの汎用実装を作成するために WebAPI をいじっています。私はほとんどのメソッドを問題なく実装できますが、重要なケースでは PUT が扱いにくいと感じています。オンラインで最も一般的に見られる実装は、単純なエンティティに対して機能します。

    [HttpPut]
    [ActionName("Endpoint")]
    public virtual T Put(T entity)
    {
        var db = GetDbContext();
        var entry = db.Entry(entity);
        entry.State = EntityState.Modified;
        var set = db.Set<T>();            
        set.Attach(entity);                     
        db.SaveChanges();
        return entity;
    }

...しかし、子リストを削除または更新しません:

    public class Invoice
    {
         ...
         public virtual InvoiceLineItem {get; set;} //Attach method doesn't address these
    }

MVC コントローラーでは、単に「UpdateModel」を使用するだけで、必要に応じて子を追加/更新/削除できますが、そのメソッドは ApiController では使用できません。データベースから元のアイテムを取得するには何らかのコードが必要であり、Include を使用して子リストを取得する必要があることは理解していますが、UpdateModel の機能を複製する最善の方法がわかりません。

    [HttpPut]
    [ActionName("Endpoint")]
    public virtual T Put(T entity)
    {
        var db = GetDbContext();
        var original = GetOriginalFor(entity); 
        //TODO: Something similar to UpdateModel(original), such as UpdateModel(original, entity);                  
        db.SaveChanges();
        return original;
    }

UpdateModel を実装する方法や、子リストを処理するような方法で Put を実装するにはどうすればよいですか?

4

1 に答える 1

1

The routine dont validate entity, but fill the pre-existent entity.

    protected virtual void UpdateModel<T>(T original, bool overrideForEmptyList = true)
    {
        var json = ControllerContext.Request.Content.ReadAsStringAsync().Result;
        UpdateModel<T>(json, original, overrideForEmptyList);
    }

    private void UpdateModel<T>(string json, T original, bool overrideForEmptyList = true)
    {
        var newValues = JsonConvert.DeserializeObject<Pessoa>(json);            
        foreach (var property in original.GetType().GetProperties())
        {
            var isEnumerable = property.PropertyType.GetInterfaces().Any(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IEnumerable<>));

            if (isEnumerable && property.PropertyType != typeof(string))
            {
                var propertyOriginalValue = property.GetValue(original, null);
                if (propertyOriginalValue != null)
                {
                    var propertyNewValue = property.GetValue(newValues, null);

                    if (propertyNewValue != null && (overrideForEmptyList || ((IEnumerable<object>)propertyNewValue).Any()))
                    {
                        property.SetValue(original, null);
                    }
                }
            }
        }

        JsonConvert.PopulateObject(json, original);
    }

    public void Post()
    {           
        var sample = Pessoa.FindById(12);
        UpdateModel(sample);            
    }
于 2015-09-29T21:26:38.043 に答える