가 아니, 비계가 의도적으로 여기 unopinionated하는 경우, 아마도 당신은 선택 목록에서 선택하기를 원할 것입니다. 아마도 체크 박스를 원할까요? 아니면 실제로 관련 항목을 인라인으로 추가/편집하고 싶습니까? 그리고 마지막으로, 한 번에 모두 올리거나 AJAX를 사용하고 싶으십니까?
따라서, 프레임 워크는 결정을 내리지 않습니다. 에 설치해야합니다. 그럼에도 불구하고 발판에 의존하는 것이 더 자주 당신을 물게 될 것입니다. 이들은 가장 기본적이고 이상적인 시나리오에서만 작동하며 응용 프로그램 요구 사항이 기본 적이거나 이상적인 경우는 언제입니까? 이 시점에서 나는 컨트롤러와 뷰를 수동으로 생성하는 것을 선호하지만, 지금은 그다지 신경 쓰지 않습니다. 그것은 발판을 다루는 것보다 더 빨리 끝나고 모든 것을 적용 취소합니다.
그래서 선택 상자 (단일 선택 또는 다중 선택)를 찾고 있기 때문에 먼저 엔티티에 대한보기 모델을 만드는 것이 좋습니다. 예를 들어, Tip
과 : 여기
public class TipViewModel
{
[Required]
public string Name { get; set; }
[Required]
[DataType(DataType.MultilineText)]
public string Description { get; set; }
[Required]
public int? SelectedPartnerId { get; set; }
public IEnumerable<SelectListItem> PartnerChoices { get; set;}
[Required]
public int? SelectedBookId { get; set; }
public IEnumerable<SelectListItem> BookChoices { get; set; }
}
, 나는 Book
선택의 ID를 추적하는 속성 (대신 첫 번째 옵션 설정에, 그들이 초기 상태로 선택 될 수있는 널 (NULL)을 사용하여) 널 (NULL) INT를 추가했습니다/Partner
엔티티에 외래 키에 대한 명시 적 속성이 표시되지 않기 때문에 괜찮습니다.하지만 약간의 차이가 있습니다. 관계를 저장하는 것이 약간 더 복잡하지는 않습니다. 명시 적 외래 키 특성이있는 경우에는보기 모델의 특성을 대신 미러링해야합니다. 나는이 선택 목록을 채우는 코드를 추상화 한
public ActionResult Create()
{
var model = new TipViewModel();
PopulateChoices(model);
return View(model);
}
...
protected void PopulateChoices(TipViewModel model)
{
model.PartnerChoices = db.Partners.Select(m => new SelectListItem
{
Value = m.Id.ToString(),
Text = m.Name
});
model.BookChoices = db.Books.Select(m => new SelectListItem
{
Value = m.Id.ToString(),
Text = string.Format("{0} by {1}", m.Name, m.Author)
});
}
코드가 사용되므로 여러 : 액션의 GET 버전 이제
, 다음과 같은 일을해야합니다 귀하의 컨트롤러 전체에서. 또한
string.Format
을
Text
값으로 사용하여 선택 목록 항목의 텍스트를 원하는대로 지정할 수 있음을 보여줍니다. 또한, 위의 코드는 분명히 create 액션을위한 것입니다.편집을하는 것은 비슷하지만 약간 다른 것 :
public ActionResult Edit(int id)
{
var tip = db.Tips.Find(id);
if (tip == null)
{
return new HttpNotFoundResult();
}
var model = new TipViewModel
{
Name = tip.Name,
Description = tip.Description,
SelectedPartnerId = tip.Partner != null ? tip.Partner.Id : new int?(),
SelectedBookId = tip.Book != null ? tip.Book.Id : new int?()
}
PopulateChoices(model);
return View(model);
}
가장 큰 차이점은 데이터베이스에서 당겨 필요가 그래서 당신은 분명 기존 인스턴스 상대하고 있다는 점이다. 그런 다음 엔티티의 데이터를 뷰 모델에 매핑하면됩니다. 다시 한번 명시 적 외래 키 특성이 없기 때문에 현재 선택된 Partner
/Book
값을 얻으려면 약간의 다리 작업을해야합니다. 그렇지 않으면 외래 키 특성 값을 직접 복사 할 수 있습니다. 또한 여기서는 수동 매핑 만하고 있지만 타사 라이브러리를 사용하면이 작업을 더 쉽게 수행 할 수 있습니다 (AutoMapper 참조).
이렇게하면보기를 구현할 수 있습니다. 엔티티를 직접 사용할 때와 똑같이 모든 것이 작동 할 것이므로 몇 가지 수정 만하면됩니다. 첫째, 당신은 당신의 뷰의 모델 선언을 변경해야합니다 :
이
@model Namespace.To.TipViewModel
그런 다음 두 개의 관련 속성에 대한 선택 목록을 추가 :
@Html.DropDownListFor(m => m.SelectedPartnerId, Model.PartnerChoices)
...
@Html.DropDownListFor(m => m.SelectedBookId, Model.BookChoices)
재미는 당신의 행동의 POST 버전에서 발생합니다. 대부분의 코드는 GET 버전에서 동일하게 유지되지만, 이제 당신은 if (ModelState.IsValid)
블록을해야합니다 :
[HttpPost]
public ActionResult Create(TipViewModel model)
{
if (ModelState.IsValid)
{
// map the data from model to your entity
var tip = new Tip
{
Name = model.Name,
Description = model.Description,
Partner = db.Partners.Find(model.SelectedPartnerId),
Book = db.Books.Find(model.SelectedBookId)
}
db.Tips.Add(tip);
db.SaveChanges();
return RedirectToAction("Index");
}
// Form has errors, repopulate choices and redisplay form
PopulateChoices(model);
return View(model);
}
편집 버전, 다시, 당신은 기존 인스턴스에 매핑하는거야 제외하고 유사하다 예 :
tip.Name = model.Name;
tip.Description = model.Description;
tip.Partner = db.Partners.Find(model.SelectedPartnerId);
tip.Book = db.Books.Find(model.SelectedBookId);
참조 용으로 모든 것이 있습니다. 귀하의 질문에 귀하의 사업체에 실제로 M2M 또는 일대 다 (one-to-many) 물건이없는 것은 아닙니다. 모든 것이 일대일이지만 컬렉션 속성이 있다면 약간 다르게 처리해야합니다. 선택한 값과 사용 가능한 선택 항목을 유지하려면 뷰 모델의 속성이 필요합니다.
public List<int> SelectedFooIds { get; set; }
public IEnumerable<SelectListItem> FooChoices { get; set; }
선택 항목 채우기도 동일합니다. 옵션은 옵션입니다. 당신이 한두 가지만 선택한다면 그것은 중요하지 않습니다.
var tip = new Tip
{
...
Foos = db.Foos.Where(m => model.SelectedFooIds.Contains(m.Id)),
}
: 데이터베이스에서 선택한 모든 항목을 선택하고 그에게 엔터티 컬렉션 속성을 설정해야 할 것로 만드는 작업에 개체 위에
매핑하지만 다른 것 그리고 편집 작업의 GET 및 POST 버전을 모두 변경해야합니다.
var model = new TipViewModel
{
...
SelectedFooIds = tip.Foos.Select(m => m.Id).ToList(),
}
을 그리고 편집 버전, 새로운 선택한 항목을 설정하십시오 GET를 들어, ID 목록에 컬렉션 속성을 응축 할 필요가
마지막으로
tip.Foos = db.Foos.Where(m => model.SelectedFooIds.Contains(m.Id);
, 귀하의 의견에, downvote 부정 http://blogs.msdn.com/b/mcsuk -
@Html.ListBoxFor(m => m.SelectedFooIds, Model.FooChoices)
+1 : 당신은 다중 선택을 가능하게
ListBoxFor
대신DropDownListFor
을 사용하십시오 soldev/archive/2013/09/20/managing-entity-relationships-with-mvc-scaffolding.aspx – InferOn