Entity framework 如何针对使用子列表的实体框架编写通用WebAPI Put方法?
我正在修补WebAPI以创建实体框架的通用实现。我能够很好地实现大多数方法,但我发现在非平凡的情况下,PUT很棘手。最常见的在线实现适用于简单实体:Entity framework 如何针对使用子列表的实体框架编写通用WebAPI Put方法?,entity-framework,asp.net-web-api,Entity Framework,Asp.net Web Api,我正在修补WebAPI以创建实体框架的通用实现。我能够很好地实现大多数方法,但我发现在非平凡的情况下,PUT很棘手。最常见的在线实现适用于简单实体: [HttpPut] [ActionName("Endpoint")] public virtual T Put(T entity) { var db = GetDbContext(); var entry = db.Entry(entity); entry.State
[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;
}
在MVC控制器中,您可以简单地使用“UpdateModel”,它将根据需要添加/更新/删除子项,但是该方法在ApicController上不可用。我知道从数据库中获取原始项需要一些代码,它需要使用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,使其能够处理子列表?例程不验证实体,而是填充先前存在的实体
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);
}
protected virtual void UpdateModel(T original,bool overrideForEmptyList=true)
{
var json=ControllerContext.Request.Content.ReadAsStringAsync().Result;
UpdateModel(json、原始、overrideForEmptyList);
}
私有void UpdateModel(字符串json,T original,bool overrideForEmptyList=true)
{
var newValues=JsonConvert.DeserializeObject(json);
foreach(原始.GetType().GetProperties()中的var属性)
{
var isEnumerable=property.PropertyType.GetInterfaces().Any(t=>t.IsGenericType&&t.GetGenericTypeDefinition()==typeof(IEnumerable));
如果(isEnumerable&&property.PropertyType!=typeof(字符串))
{
var propertyOriginalValue=property.GetValue(原始,空);
if(propertyOriginalValue!=null)
{
var propertyNewValue=property.GetValue(newValues,null);
if(propertyNewValue!=null&(overrideForEmptyList | | |((IEnumerable)propertyNewValue).Any())
{
property.SetValue(原始,空);
}
}
}
}
PopulateObject(json,原始);
}
公共空缺职位()
{
var-sample=Pessoa.FindById(12);
更新模型(样本);
}
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);
}