.NET 4.0 Linq to SQL - обновление объекта не работает - PullRequest
0 голосов
/ 17 октября 2011

Я создаю простое приложение MVC Movie, используя шаблон репозитория и библиотеку классов для моих классов 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>

Ответы [ 2 ]

1 голос
/ 17 октября 2011

Вы забываете, что http - это система без сохранения состояния.Каждая полученная страница является отдельным запросом, и каждый набор объектов уничтожается в конце каждого запроса.

Итак, объекты, возвращаемые вашим get, не существуют в вашем посте, потому что это совершенно отдельный запрос.На самом деле механизм связывания моделей по умолчанию создает новый экземпляр объекта Movie, а не изменяет содержимое того, который вы ранее вернули.

Таким образом, обновление не будет работать, поскольку L2S не знает, что вашВновь созданный объект Movie должен быть обновлен.

1 голос
/ 17 октября 2011

В вашем методе 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");
}

Чтобы это работало, вы также должны включить в форму идентификатор своего фильма (в виде скрытого поля), чтобы он мог быть опубликован браузером и таким образом позволить вамразличать обновление одного фильма от обновления другого.Например:

    <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 Man , вам не нужно добавлять это скрытое поле, если ваш URL содержит идентификатор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...