ViewModel не связывает виртуальный класс - PullRequest
0 голосов
/ 20 февраля 2012

Это моя ViewModel:

 public class PlayerViewModel
    {
        PlayerRepository repo = new PlayerRepository();

        public Player Player { get; set; }
        public int SelectedUserID { get; set; }
        public SelectList Users { get; set; }


        public PlayerViewModel()
        {
            Player = new Player();
        }
        public PlayerViewModel(Player player)
        {
            Player = player;

            SelectedUserID = 0;
        }
   }

Это в моем контроллере (для редактирования):

    [Authorize]
    public ActionResult Upravit(int id)
    {

        var player = repo.Retrieve(id);
        var playerView = new PlayerViewModel(player);
        playerView.Users = new SelectList(repo.GetUsers(), "UserID", "UserName");
        return View(playerView);
    }
    [Authorize,HttpPost]
    public ActionResult Upravit(int id, PlayerViewModel playerView)
    {
        if (ModelState.IsValid)
        {
            playerView.Player.User = repo.GetUserByID(playerView.SelectedUserID);

            repo.Save(playerView.Player);
            return RedirectToAction("Podrobnosti", new { id = playerView.Player.PlayerID });
        }
        return View(playerView);
    }

и репо:

public User GetUserByID(int id)
        {
            return db.Users.Find(id);
        }

public int Save(Player player)
    {
        db.Entry(player).State = player.PlayerID == 0 ?
            EntityState.Added : EntityState.Modified;
        db.SaveChanges();
        return player.PlayerID;
    }

Моя проблема в том, что я получаю в httppost действительную модель просмотра, я добавляю пользователя в проигрыватель (это пользовательский класс, а в классе проигрывателя - виртуальный пользователь) и в режиме отладки все выглядит нормально (игрок содержит нужного пользователя), но в следующий раз, когда я в другом представлении пытаюсь получить плеер, его свойство с User равно null. Я проверил это в базе данных и нет int в столбце с UserID. Так может кто-нибудь может помочь мне, где проблема? Почему не экономит?

Изменить: Я добавил этот код в свой репозиторий:

private bool disposed = false;

        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    db.Dispose();
                }
            }
            this.disposed = true;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

и изменить в контроллере на это:

[Authorize,HttpPost]
        public ActionResult Upravit(int id, PlayerViewModel playerView)
        {
            if (ModelState.IsValid)
            {
                using (PlayerRepository playerRepository = new PlayerRepository())
                {
                    playerView.Player.User = playerRepository.GetUserByID(playerView.SelectedUserID);

                    playerRepository.Save(playerView.Player);
                    return RedirectToAction("Podrobnosti", new { id = playerView.Player.PlayerID });
                }
            }
            return View(playerView);
        }

но это не помогло.

Edit2 Мой игрок и пользовательские классы:

 public class User
 {
    public User()
    {
    }
    public User(int userId, string userName, string firstName, string surname, string password, string email)
    {
        UserID = userId;
        UserName = userName;
        Name = firstName;
        Surname = surname;
        Password = password;
        Email = email;
        IsActivated = false;
    }

    [HiddenInput(DisplayValue = false)]
    public int UserID { get; set; }

    [Display(Name="Uživatelské jméno")]
    [Required(ErrorMessage = "Je potřeba vyplnit uživatelské jméno.")]
    [StringLength(20)]
    public string UserName { get; set; }

    public string Name { get; set; }

    public string Surname { get; set; }
    [Display(Name = "Heslo")]
    [DataType(DataType.Password)]
    [Required(ErrorMessage = "Je potřeba vyplnit heslo.")]
    [StringLength(30)]
    public string Password { get; set; }

    [Display(Name = "E-mail")]
    [DataType(DataType.EmailAddress)]
    [Required(ErrorMessage = "Je potřeba vyplnit Váš e-mail.")]
    [StringLength(30)]
    public string Email { get; set; }
    public IIdentity Identity { get; set; }

    public string ImagePath { get; set; }

    public virtual ICollection<Article> Articles { get; set; }
    public virtual ICollection<Comment> Comments { get; set; }
    public virtual ICollection<Post> Posts { get; set; }
    public virtual ICollection<Topic> Topics { get; set; }

    public int RoleId { get; set; }
    public virtual Role Role { get; set; }

    public bool IsActivated { get; set; }
    public string EmailKey { get; set; }
}
}

 public class Player
{
    [Key]
    public int PlayerID { get; set; }

    [Required]
    public string Name { get; set; }
    [Required]
    public string Surname { get; set; }

    public string PhotoUrl { get; set; }

    public string Post { get; set; }

    public virtual Team Team { get; set; }

    public virtual User User { get; set; }
}

Я добавил с помощью repo каждый метод в Controller и добавил метод Dispose на контроллер, и теперь у меня проблема с отображением данных. Например, когда я попытался показать Player.User.UserName (я вручную добавил некоторых игроков в проигрыватели), он говорит, что экземпляр ObjectDataContext был удален и не может быть использован.

1 Ответ

0 голосов
/ 20 февраля 2012

Кажется, необходимо утилизировать ObjectContext; в противном случае каждый раз появляются различные экземпляры ObjectContext, и вы можете столкнуться с проблемами при выполнении запросов среди объектов контекстов.

Реализуйте IDisposable для вашего класса репозитория: вызовите метод Dispose для базового ObjectContext экземпляра класса.

Код клиента:

using (PlayerRepository playerRepository = new PlayerRepository())
{
    // Perform queries, etc.
}

Обновление

Чтобы упростить удаление хранилища, просто переопределите Dispose метод класса Controller -производного: вызовите Dispose для хранилища здесь. Платформа ASP.NET MVC автоматически вызовет Controller.Dispose() в конце запроса.

Обновление

Для определения отношения необходимо определить свойство с именем <entity>Id.

public class Player
{
    // Having a property called <entity>Id defines a relationship.
    public int UserId { get; set; }
    public virtual User User { get; set; }
}

Надеюсь, это поможет.

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