.NET 4.0 Linq to SQL - 对象更新不起作用
我正在构建一个简单的 MVC 电影应用程序,使用存储库模式和用于我的 Linq to SQL 类的类库。我似乎无法将我的对象更新回数据库。我现在丢失了一些东西,确定它是什么:
public class MovieRepository : BaseRepository, IMovieRepository
{
/// <summary>
/// Updates the specified movie.
/// </summary>
public void Update()
{
GetDataContext.SubmitChanges();
}
/// <summary>
/// Fetches the by id.
/// </summary>
/// <param name="id">The id.</param>
public Movie FetchById(int id)
{
Movie movie = (from n in GetDataContext.Movies
where n.ID == id
select n).First();
return movie;
}
}
BaseRepository.cs
public abstract class BaseRepository
{
private static VideoStoreDBDataContext _videoStoreDbDataContext;
protected static VideoStoreDBDataContext GetDataContext
{
get
{
if (_videoStoreDbDataContext == null)
{
_videoStoreDbDataContext = new VideoStoreDBDataContext();
}
return _videoStoreDbDataContext;
}
}
}
HomeController
public ActionResult EditMovie(int Id)
{
Movie movie = _movieRepository.FetchById(Id);
if (movie == null)
return RedirectToAction("Error", "Home");
return View(movie);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditMovie(Movie movie)
{
if (!ModelState.IsValid)
return View(movie);
// NOTE: movie object does infact contain changes made using the VIEW.
_movieRepository.Update();
return RedirectToAction("Index");
}
View
<% using (Html.BeginForm()) {%>
<fieldset>
<legend>Details</legend>
<p>
<label for="Title">Title:</label><br/>
<%= Html.TextBox("Title", Model.Title) %>
<%= Html.ValidationMessage("Title", "*") %>
</p>
<p>
<input type="submit" value="Update Movie" />
</p>
</fieldset>
<% } %>
<div>
<%=Html.ActionLink("Back to List", "Index") %>
</div>
I'm building a simple MVC Movie Application, using a repository pattern and Class Library for my Linq to SQL Classes. I can't seem to get my objects to UPDATE back to the database.. I'm missing something now sure what it is:
public class MovieRepository : BaseRepository, IMovieRepository
{
/// <summary>
/// Updates the specified movie.
/// </summary>
public void Update()
{
GetDataContext.SubmitChanges();
}
/// <summary>
/// Fetches the by id.
/// </summary>
/// <param name="id">The id.</param>
public Movie FetchById(int id)
{
Movie movie = (from n in GetDataContext.Movies
where n.ID == id
select n).First();
return movie;
}
}
BaseRepository.cs
public abstract class BaseRepository
{
private static VideoStoreDBDataContext _videoStoreDbDataContext;
protected static VideoStoreDBDataContext GetDataContext
{
get
{
if (_videoStoreDbDataContext == null)
{
_videoStoreDbDataContext = new VideoStoreDBDataContext();
}
return _videoStoreDbDataContext;
}
}
}
HomeController
public ActionResult EditMovie(int Id)
{
Movie movie = _movieRepository.FetchById(Id);
if (movie == null)
return RedirectToAction("Error", "Home");
return View(movie);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditMovie(Movie movie)
{
if (!ModelState.IsValid)
return View(movie);
// NOTE: movie object does infact contain changes made using the VIEW.
_movieRepository.Update();
return RedirectToAction("Index");
}
View
<% using (Html.BeginForm()) {%>
<fieldset>
<legend>Details</legend>
<p>
<label for="Title">Title:</label><br/>
<%= Html.TextBox("Title", Model.Title) %>
<%= Html.ValidationMessage("Title", "*") %>
</p>
<p>
<input type="submit" value="Update Movie" />
</p>
</fieldset>
<% } %>
<div>
<%=Html.ActionLink("Back to List", "Index") %>
</div>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
![扫码二维码加入Web技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在您的方法
EditMovie
中,您作为参数接收的对象movie
实际上并不是数据库绑定的对象。它是由 MVC 运行时为您构建的,而您的 DataContext 对此一无所知。因此,当您调用Update()
时,DataContext
不会看到任何写入数据库的更改。您应该做的是在数据库中找到该对象,然后将方法参数中的所有字段复制到其中,然后调用
Update()
。像这样:为此,您还必须在表单中包含您的电影 ID(作为隐藏字段),以便浏览器可以将其发回,从而使您能够区分对一部电影的更新和对其他。就像这样:
编辑:正如Mystere Man指出的那样,如果您的URL包含Id,则不需要添加此隐藏字段。
In your method
EditMovie
, the objectmovie
that you receive as the argument, is not actually a database-bound object. It gets constructed for you by MVC runtime, and yourDataContext
has no knowledge of it. Therefore, when you callUpdate()
, theDataContext
doesn't see any changes to write to the database.What you should do instead is find this object in the database, then copy all fields from the method's argument into it, and then call
Update()
. Like so:For this to work, you also have to include your Movie's ID in your form (as a hidden field), so that it may be posted back by the browser, and thus enable you to distinguish update to one movie from update to another. Like so:
EDIT: As Mystere Man pointed out, you do not need to add this hidden field if your URL contains the Id.
您忘记了 http 是一个无状态系统。提供服务的每个页面都是一个单独的请求,并且每组对象都会在每个请求结束时被销毁。
因此,您的 get 返回的对象在您的帖子中不存在,因为这是一个完全独立的请求。实际上,默认模型绑定器正在创建 Movie 对象的一个新实例,而不是修改您之前返回的实例的内容。
所以更新不会起作用,因为 L2S 不知道你新创建的 Movie 对象应该更新。
You are forgetting that http is a stateless system. Each page that gets served is a seperate request, and each set of objects are destroyed at the end of each request.
So, the objects returned by your get do not exist in your post, because this is a completely seperate request. In reality, the Default Model Binder is creating a new instance of your Movie object, not modifying the contents of the one you previously returned.
So the update won't work, because L2S doesn't know that your newly created Movie object should be updated.