1

私は MVC と EF の世界は初めてです。最初にコードを使用して MVC 4 EF 5 をターゲットにしています。

1 つのビューを使用して 2 つの関連するモデルを編集するためのベスト プラクティスを探しています。簡単にするために、次の 2 つのモデルがあります。

namespace AddressBook.Models
{
    public class Contact
    {
        public int ID { get; set; }
        public string First_Name { get; set; }
        public string Last_Name { get; set; }
        public List<PhoneNumber> PhoneNumbers { get; set; }
     }
}

namespace AddressBook.Models
{
    public class PhoneNumber
    {
        public int ID { get; set; }
        public string Number { get; set; }
        public bool Primary { get; set; }
    }
}

次のコンテキストで:

using System.Data.Entity;
namespace AddressBook.Models
{
    public class DataContext : DbContext
    {
        public DbSet<Contact> Contacts { get; set; }
        public DbSet<PhoneNumber> PhoneNumbers { get; set; }
    }
}

Contact と PhoneNumber の関係は 1 対多ですが、Primary が true に設定されているときに first_name、last_name、および Number を編集できるようにしたいので、連絡先レコードごとに 1 つの電話番号のみを編集します。

ViewModel の使用を指す同様の投稿を見たことがありますが、私が見た唯一のビューモデルの例は、ドロップダウンの情報を渡すときにビューバッグの代わりに使用された場合です。

いくつか質問があると思います:

  1. ViewModel は以下のようになりますか?

    public class ContactPrimaryNumberViewModel
    {
        public Contact ContactToEdit {get; set;}
        public PhoneNumber PhoneNumberToEdit {get;set;}
    }
    
  2. edit(post) と edit(get) はどのようになりますか?

これに頭を悩ませるのに役立つ助けがあれば幸いです...

連絡先に電話番号が関連付けられていない場合にサポートするように変更された Edit(get) は次のとおりです。

' // GET: /Contact/Edit/5

    public ActionResult Edit(int id = 0)
    {
        ContactPrimaryNumberViewModel ContactPrimaryNumber = (from pn in db.PhoneNumbers
                                                              where pn.ContactID == id && pn.Primary == true
                                                              select new ContactPrimaryNumberViewModel { ContactID = pn.ContactID, First_Name = pn.Contact.First_Name, Last_Name = pn.Contact.Last_Name, Number = pn.Number }).SingleOrDefault();



        if (ContactPrimaryNumber == null)
        {
            ContactPrimaryNumber = (from c in db.Contacts
                                                                  where c.ID == id
                                                                  select new ContactPrimaryNumberViewModel { ContactID = c.ID, First_Name = c.First_Name, Last_Name = c.Last_Name, Number = null }).Single();

        }
        return View(ContactPrimaryNumber);
    }'

みんなの助けを借りた後の最終的な解決策は次のとおりです。

モデル:

    public class PhoneNumber
{
    public int ID { get; set; }
    public string Number { get; set; }
    public bool Primary { get; set; }

    [Required]
    public int ContactID { get; set; }
    public Contact Contact { get; set; }

}

    public class Contact
{
    public int ID { get; set; }
    public string First_Name { get; set; }
    public string Last_Name { get; set; }
    public List<PhoneNumber> PhoneNumbers { get; set; }


}

コントローラーの編集 (get と post)

        // GET: /Contact/Edit/5

    public ActionResult Edit(int id = 0)
    {

        ContactPrimaryNumberViewModel ContactPrimaryNumber = (from c in db.Contacts
                                                              join pn in db.PhoneNumbers
                                                              on c.ID equals pn.ContactID into outer
                                                              from _pn in outer.Where(p => p.Primary ==true).DefaultIfEmpty()
                                                              where c.ID == id 
                                                              select new ContactPrimaryNumberViewModel { ContactID = c.ID, First_Name = c.First_Name, Last_Name = c.Last_Name, Number = ((_pn == null) ? "" : _pn.Number) }).FirstOrDefault();

        if (ContactPrimaryNumber == null)
        {
            return HttpNotFound();
        }
        return View(ContactPrimaryNumber);
    }

    // POST: /Contact/Edit/5

    [HttpPost]
    public ActionResult Edit(ContactPrimaryNumberViewModel ContactPrimaryNumber)
    {
        Contact c = db.Contacts.Find(ContactPrimaryNumber.ContactID);
        PhoneNumber pn = db.PhoneNumbers.FirstOrDefault(x => x.ContactID == ContactPrimaryNumber.ContactID && x.Primary == true);

        if (ModelState.IsValid)
        {
            c.First_Name = ContactPrimaryNumber.First_Name;
            c.Last_Name = ContactPrimaryNumber.Last_Name;

            if (pn == null) //if there is no phone number associated with the contact in the DB
            {
                if (!String.IsNullOrEmpty(ContactPrimaryNumber.Number))
                {
                    //Add a new phonenumber in the database

                    PhoneNumber Px = new PhoneNumber();

                    Px.ContactID = ContactPrimaryNumber.ContactID;
                    Px.Number = ContactPrimaryNumber.Number;
                    Px.Primary = true;

                    db.PhoneNumbers.Add(Px);

                }

            }
            else //if there is a phone number associated with the contactin the DB
            {
                if (String.IsNullOrEmpty(ContactPrimaryNumber.Number))
                {
                    //delete the existing number
                    db.PhoneNumbers.Remove(pn);

                }
                else
                {
                    //modify the existing number
                    pn.Number = ContactPrimaryNumber.Number;
                }
            }


            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(c);
    }

そしてビューモデル

    public class ContactPrimaryNumberViewModel
{

    public int ContactID { get; set; }
    public string First_Name { get; set; }
    public string Last_Name { get; set; }
    public string Number { get; set; }


}

あなたの助けに再び感謝します

4

2 に答える 2

0

さて、これを試してください:

電話番号

public class PhoneNumber
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public string Number { get; set; }
    public bool Primary { get; set; }

    [ForeignKey("Contact"), DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int? ContactId { get; set; }

    public virtual Contact Contact { get; set; }
}

コンタクト

public class Contact
{  
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ContactId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public List<PhoneNumber> PhoneNumbers { get; set; }
}

SaveContact : Repositories または Ef クラスの設定方法によって異なります。これは、EfRepository 実装または EfDb クラスのいずれかに入れることができます。

public void SavePlayer(Contact contact)
    {
        using (var context = new EfDb())
        {                
            if (contact.ContactId == 0)
            {                    
                context.Contacts.Add(contact);
            }
            else if (contact.ContactId > 0)
            {
                var currentContact = context.Contacts
                    .Include(c => c.PhoneNumber)
                    .Single(c => c.ContactId== contact.ContactId);

                context.Entry(currentContact).CurrentValues.SetValues(contact);
                currentContact.PhoneNumber= contact.PhoneNumber;
            }
            context.SaveChanges();
        }
    }

アクションを編集

    [HttpGet]
    public ActionResult Edit(int id)
    {
        var contact= _dataSource.Contacts.FirstOrDefault(c => c.Id == id);

        return View(player);
    }

    [HttpPost]
    public ActionResult Edit(Contact contact)
    {
        try
        {
            if (ModelState.IsValid)
            {
                _dataSource.SaveContact(contact);
                return RedirectToAction("About", "Home");
            }
        }
        catch (Exception)
        {
            ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
        }            
        return View(contact);
    }

ビュー

あなたのContact View Folder追加EditorTemplates folderで。次に、Scaffold aを作成し、そのモデルCreate Strongly Typed PhoneNumber Partial View to this folderと同じ名前を付けます。PhoneNumber

足場にCreate Strongly Typed Contact View名前を付けるCreate

@Html.EditorFor(model => model.PhoneNumber)次に、マスター Create View に追加します。

于 2013-04-14T00:31:19.720 に答える
0

ビューモデルは次のようになるはずです。

public class ContactPrimaryNumberViewModel
{
    public int ID { get; set; }
    public string First_Name { get; set; }
    public string Last_Name { get; set; }
    public string Number { get; set; }
}

そして、更新は次のようになります。

Contact c = context.Contacts.Find(id);
PhoneNumber p = context.PhoneNumbers
    .FirstOrDefault(x => x.id == id && x.Primary == true);
//validate input
//update as necessary
//SaveChanges() etc...

あなたのコメントから-モデルクラスを新しくしますContactPrimaryNumberViewModel

var ContactPrimaryNumber = 
    from pn in db.PhoneNumbers 
    where pn.ContactID == id && pn.Primary == true 
    select new ContactPrimaryNumberViewModel() {
        ContactID = pn.ContactID, 
        First_Name = pn.Contact.First_Name, 
        Last_Name = pn.Contact.Last_Name, 
        Number = pn.Number
    };
于 2013-04-13T22:18:41.377 に答える