我试图使用AngularJS使用$ http.put方法更新一些数据。但是,我已经尝试了几种调用此方法的变体,并且它一再未能在我的控制器中调用put方法 - 或者,如果它,它创建一个新实体而不是更新旧数据。这是我的代码:
(我知道我的api的其余部分可以作为帖子工作并且可以很好地用于汽车)
CarController.cs
public void Put(int CarId, [FromBody] Car c)
{
System.Diagnostics.Debug.WriteLine("CarController.Put() Called");
c.CarId = CarId;
if (!_repo.UpdateCar(c) || !_repo.Save())
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
}
存储库(" _repo"):
public bool UpdateCar(Car car)
{
if (car == null)
{
throw new ArgumentNullException("car");
}
int index = _ctx.Cars.ToList().FindIndex(c => c.CarId == car.CarId);
if (index == -1)
{
return false;
}
_ctx.Cars.ToList().RemoveAt(index);
_ctx.Cars.Add(car);
return true;
}
AngularJS脚本:
var _linkPersonAndCar = function(person, car) {
var deferred = $q.defer();
alert("_linkPersonAndCar()\nPerson = " + JSON.stringify(person) + "\nCar = " + JSON.stringify(car));
//Update car
car.persons.splice(0, 0, person);
alert("_linkPersonAndCar() attempting put");
$http.put("/api/cars/"+car.carId, car)
.then(function ()
{
alert("_linkPersonAndCar() - Success!");
deferred.resolve();
},
function ()
{
alert("_linkPersonAndCar() - Failure updating car");
deferred.reject();
});
alert("_linkPersonAndCar() - Complete");
return deferred.promise;
};
答案 0 :(得分:2)
好吧,请参阅我的评论,以获取有关将其分解为单独问题的建议。但我发现您的EF代码至少存在一个问题:
_ctx.Cars.ToList().RemoveAt(index);
调用ToList()会创建一个与提供程序断开连接的列表(EF Context),并创建一个内存列表。然后,您从该列表中删除该项目,这将无法完成任何任务,因为您不会在任何后续代码中使用该列表。这不会从数据库中删除实体,我认为这是您的意图。在任何情况下,您都希望更新现有汽车,而不是删除并重新添加(至少是我的假设)。
_ctx.Cars.Add(car);
这将始终添加一辆新车。
你想要更像的东西:
var ctxCar = _ctx.Cars.SingleOrDefault(c => c.CarId = car.CarId);
if (ctxCar == null)
{
return false;
}
//here you want map properties from your parameter to your context's car
ctxCar.Property1 = car.Property1;
//etc.
return true;
答案 1 :(得分:0)
_ctx
是EF上下文吗?如果是这样,附加应该有效:
// connect to context
_ctx.Cars.Attach(car);
// check for updated info
var entry = _ctx.Entry(car);
entry.Property(e => e.NumberOfDoors).IsModified = true;
// save changes
_ctx.SaveChanges();
否则,菲尔是正确的:
_ctx.Cars.Add(car);
将始终为您提供新记录