2011-10-17 1 views
0

저는 Linq to SQL 클래스를위한 저장소 패턴과 클래스 라이브러리를 사용하여 간단한 MVC Movie Application을 구축하고 있습니다. 나는 .. 나는 그것이 무엇인지 지금 확인 뭔가 누락 데이터베이스에 다시 업데이트하려면 내 개체를 얻을 수없는 것 :.NET 4.0 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"); 
} 

보기

<% 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> 

답변

1

EditMovie 메서드에서 사용자가 인수로받는 movie 개체는 실제로 데이터베이스 바인딩 개체가 아닙니다. MVC 런타임에 의해 생성되며, DataContext에 대한 지식이 없습니다. 따라서 Update()을 호출하면 DataContext에 데이터베이스에 쓸 변경 내용이 표시되지 않습니다.

대신 데이터베이스에서이 개체를 찾은 다음 메서드의 인수에서 모든 필드를 복사 한 다음 Update()을 호출하십시오. 그래서 같이이 들어

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult EditMovie(Movie movie) 
{ 
    if (!ModelState.IsValid) 
     return View(movie); 

    var existingMovie = _movieRepository.FetchById(movie.Id); 
    existingMovie.Title = movie.Title; 
    _movieRepository.Update(); 

    return RedirectToAction("Index"); 
} 

이 작동하려면, 당신은 또한 다시 브라우저에 의해 게시 될 수 있도록, (숨겨진 필드로) 양식에 영화의 ID를 포함해야하고, 따라서 구별 할 수 있습니다 한 영화를 다른 영화로 업데이트하십시오. 그래서 같이 :

<legend>Details</legend> 
    <p> 
     <label for="Title">Title:</label><br/> 
      <%= Html.TextBox("Title", Model.Title) %> 
      <%= Html.ValidationMessage("Title", "*") %> 
      <%= Html.HiddenFor(m => m.Id) %> //<------ 
    </p> 

편집 : Mystere 남자이 지적한 것처럼, 당신은 당신의 URL가 이드가 포함 된 경우이 숨겨진 필드를 추가 할 필요가 없습니다.

+1

사실, URL에서 id를 가져 오기 위해 post 매개 변수에 id 매개 변수를 추가하는 것만으로 숨길 필요가 없습니다. –

+0

@Mystere : 매개 변수가 URL에 있으면 매개 변수를 메서드에 실제로 추가 할 필요가 없습니다. URL 매개 변수는 모델 객체에 자동으로 매핑됩니다. 그러나 게시글에는 어떤 라우팅 구성이 사용되는지는 명시되어 있지 않으며 분명히 OP의 낮은 경험을 고려할 때 여기서는 안전한 쪽을 선호합니다. –

1

http가 상태없는 시스템이라는 사실을 잊고 있습니다. 제공되는 각 페이지는 별도의 요청이며 각 요청의 끝에서 각 개체 집합이 삭제됩니다.

그래서 완전히 다른 요청이기 때문에 get에 의해 반환 된 개체가 게시물에 존재하지 않습니다. 실제로 기본 모델 바인더는 이전에 반환 한 내용을 수정하지 않고 Movie 객체의 새 인스턴스를 만듭니다.

L2S는 새로 생성 된 Movie 개체를 업데이트해야한다는 것을 모르기 때문에 업데이트가 작동하지 않습니다.

관련 문제