6

3つのモデルを組み合わせて1つのビューモデルを作成しています。[編集]をクリックすると、そのビューモデルを編集できるようになります。これがどのように機能するか(どこでも)の簡単な例を見つけることができません。

正しい道を進んでいるかどうかはわかりません。データでビューを取得することができます。この時点で、私はそれを保存することができません。

どんな助けでもいただければ幸いです。

ありがとう!

モデル:

    public class Person
{
    [Key]
    public int Id { get; set; }

    [MaxLength(20)]
    [Required(ErrorMessage = "First name is required.")]
    public string FirstName { get; set; }

    [MaxLength(20)]
    [Required(ErrorMessage = "Last name is required.")]
    public string LastName { get; set; }
    [MaxLength(40)]
    [Required(ErrorMessage = "Email is required.")]
    public string Email { get; set; }
    [MaxLength(20)]
    [DataType(DataType.PhoneNumber)]
    public string Phone { get; set; }

    public bool Active { get; set; }
}


    public class ClientContact
{
    [Key]
    [ForeignKey("Person")]
    public int ClientPersonId { get; set; }
    public int ClientId { get; set; }
    [MaxLength(40)]
    public string Title { get; set; }

    public Person Person { get; set; }
    [ForeignKey("ClientId")]
    public Client Client { get; set; }
}

    public class Client
{
    [Key]
    public int ClientId { get; set; }
    public string Name { get; set; }
    public bool Active {get;set;}

}

モデルの表示:

    public class ClientContactViewModel
{

    private SimplexDB db = new SimplexDB();


    public ClientContactViewModel()
    { 

    }


    public ClientContactViewModel(int id)
    {
        ClientPersonId = id;
        InitializeClientContact();
    }

    public int ClientPersonId { get; set; }


    [Display(Name = "First Name")]
    public string FirstName { get; set; }
    [Display(Name = " Last Name")]
    public string LastName { get; set; }
    [Display(Name = "Title")]
    public string Title { get; set; }
    [Display(Name = "Email Address")]
    public string Email { get; set; }
    [Display(Name = "Phone")]
    public string Phone { get; set; }
    [Display(Name = "Client Name")]
    public int ClientId { get; set; }


    public SelectList Clients
    {
        get
        {
            return new SelectList(db.Clients, "ClientId", "Name");

        }
    }

    private void InitializeClientContact()
    {
        var contact = db.ClientPersons.Include("Person").Where(x => x.ClientPersonId == ClientPersonId).SingleOrDefault();
        if (contact != null)
        {
            FirstName = contact.Person.FirstName;
            LastName = contact.Person.LastName;
            Title = contact.Title;
            Email = contact.Person.Email;
            Phone = contact.Person.Phone;
            ClientId = contact.ClientId;

        }
    }



}

コントローラ:

                public class ClientContactController : Controller
    {
        private database db = new database();

//
        // GET: /ClientContact/Edit/5

        public ActionResult Edit(int id)
        {
            return View(new ClientContactViewModel(id));
        }

        //
        // POST: /ClientContact/Edit/5

        [HttpPost]
        public ActionResult Edit(ClientContactViewModel model)
        {
            if (ModelState.IsValid)
            {
                db.Entry(model).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(model);
        }
}

db.Entry(model).Stateでエラーが発生します...「エンティティタイプClientContactViewModelは、現在のコンテキストのモデルの一部ではありません。」

4

2 に答える 2

12

ViewModel はエンティティではありません。ViewModel をエンティティにマップしてから、エンティティの状態を変更済みに設定する必要があります。

基本的に、これはビューモデルの値でエンティティの値を設定する必要があることを意味します。AutoMapperを使用するか、手動で処理できます。

    [HttpPost]
    public ActionResult Edit(ClientContactViewModel model)
    {
        if (ModelState.IsValid)
        {
            ClientContact contact = db.ClientPersons.Include("Person")
                                    .Where(x => x.ClientPersonId == model.ClientPersonId)
                                    .SingleOrDefault();
            contact.FirstName = model.FirstName;
            // etc
            db.Entry(contact).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(model);
    }

MVC で ViewModel を使用する優れた方法については、http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/を参照してください。

また、ViewModel でデータ アクセスを行わないことを強くお勧めします。コントローラーでそれを行うか、コントローラーで使用されるリポジトリでそれを行うことをお勧めします。モデル バインディングは、ロジックを持つモデルではうまく機能しません (つまり、単純な get/set プロパティ以外のものを含めるべきではありません)。

于 2012-06-25T18:56:53.873 に答える
3

GET アクションで、モデルのプロパティをビューモデルに移動する必要があります。POST アクションで、データベースから元のモデルを取得し、ビュー モデルからのデータでモデルを更新してから、変更を保存します。モデルは基本的に、データベース内のテーブルの表現です。ビューモデルは、画面に表示されるものです。

[HttpPost] 
    public ActionResult Edit(ClientContactViewModel model) 
    { 
        if (ModelState.IsValid) 
        { 

           var client = db.Client.Where(c => c.Id = model.ClientPersonId);
           client.FirstName = model.FirstName;

           ...etc through all your properties and other models...


            db.Entry(model).State = EntityState.Modified; 
            db.SaveChanges(); 
            return RedirectToAction("Index"); 
        } 
        return View(model); 
    } 

これを行うためのより洗練された方法がありますが、これは抽象化のないアイデアを表しています。

于 2012-06-25T19:01:02.797 に答える