如何将子模型/表的主键保存为父模型/表中的外键?

时间:2017-03-03 20:00:41

标签: asp.net-mvc

我正在学习MVC,为一个乐谱库存系统的ASP.NET MVC项目工作,并有两个表:ScoreList和KeySignature。 KeySignature表具有主键(Id)和KeySignatureName。我有另一张桌子,我正在使用ScoreListItems,但我认为这与我的问题无关。

我想弄清楚如何做一些事情。

1)当我创建一个新的ScoreList记录时,我希望KeySignature字段是一个下拉列表,用于从KeySignature表中填充KeySignatureNames。

2)当我保存记录时,我希望ScoreList表存储KeySignatureId。

当我写这篇文章时,听起来应该很容易,但我整个星期都在摸不着头脑,无法弄明白。任何帮助将不胜感激。

这是我到目前为止所做的:

Key Signature模型:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CreswellSolution.Model
{
    public class KeySignature
    {
        public int KeySignatureId { get; set; }
        public string KeySignatureName { get; set; }

    }
}

ScoreListModel:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CreswellSolution.Model
{
    public class ScoreList : IObjectWithState
    {
        public ScoreList()
        {
            ScoreListItems = new List<ScoreListItem>();
        }

        public int ScoreListId { get; set; }
        public string ScoreListName { get; set; }
        public string ScoreListComposer { get; set; }
        public int KeySignatureId { get; set; }

        public virtual List<ScoreListItem> ScoreListItems  { get; set; }

        public ObjectState ObjectState { get; set; }
    }
}

ScoreListViewModel:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using CreswellSolution.Model;

namespace CreswellSolution.Web.ViewModels
{
    public class ScoreListViewModel : IObjectWithState
    {
        public ScoreListViewModel()
        {
            ScoreListItems = new List<ScoreListItemViewModel>();
            ScoreListItemsToDelete = new List<int>();
        }

        public int ScoreListId { get; set; }
        public string ScoreListName { get; set; }
        public string ScoreListComposer { get; set; }
        public int KeySignatureId { get; set; }

        public List<ScoreListItemViewModel> ScoreListItems { get; set; }

        public List<int> ScoreListItemsToDelete { get; set; }

        public string MessageToClient { get; set; }

        public ObjectState ObjectState { get; set; }
    }
}

助手查看模型:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using CreswellSolution.Model;

namespace CreswellSolution.Web.ViewModels
{
    public static class Helpers
    {
        public static ScoreListViewModel CreateScoreListViewModelFromScoreList(ScoreList scoreList)
        {
            ScoreListViewModel scoreListViewModel = new ScoreListViewModel();
            scoreListViewModel.ScoreListId = scoreList.ScoreListId;
            scoreListViewModel.ScoreListName = scoreList.ScoreListName;
            scoreListViewModel.ScoreListComposer = scoreList.ScoreListComposer;
            scoreListViewModel.KeySignatureId = scoreList.KeySignatureId;
            scoreListViewModel.ObjectState = ObjectState.Unchanged;

            foreach (ScoreListItem scoreListItem in scoreList.ScoreListItems)
            {
                ScoreListItemViewModel scoreListItemViewModel = new ScoreListItemViewModel();
                scoreListItemViewModel.ScoreListItemId = scoreListItem.ScoreListItemId;
                scoreListItemViewModel.PartName = scoreListItem.PartName;
                scoreListItemViewModel.TotalParts = scoreListItem.TotalParts;
                scoreListItemViewModel.PartsCheckedOut = scoreListItem.PartsCheckedOut;

                scoreListItemViewModel.ObjectState = ObjectState.Unchanged;

                scoreListItemViewModel.ScoreListId = scoreList.ScoreListId;

                scoreListViewModel.ScoreListItems.Add(scoreListItemViewModel);
            }

            return scoreListViewModel;
        }


        public static ScoreList CreateScoreListFromScoreListViewModel(ScoreListViewModel scoreListViewModel)
        {
            ScoreList scoreList = new ScoreList();
            scoreList.ScoreListId = scoreListViewModel.ScoreListId;
            scoreList.ScoreListName = scoreListViewModel.ScoreListName;
            scoreList.ScoreListComposer = scoreListViewModel.ScoreListComposer;
            scoreList.KeySignatureId = scoreListViewModel.KeySignatureId;
            scoreList.ObjectState = scoreListViewModel.ObjectState;

            int temporaryScoreListItemId = -1; 

            foreach (ScoreListItemViewModel scoreListItemViewModel in scoreListViewModel.ScoreListItems)
            {
                ScoreListItem scoreListItem = new ScoreListItem();
                scoreListItem.PartName = scoreListItemViewModel.PartName;
                scoreListItem.TotalParts = scoreListItemViewModel.TotalParts;
                scoreListItem.PartsCheckedOut = scoreListItemViewModel.PartsCheckedOut;

                scoreListItem.ObjectState = scoreListItemViewModel.ObjectState;

                if (scoreListItemViewModel.ObjectState != ObjectState.Added)
                    scoreListItem.ScoreListItemId = scoreListItemViewModel.ScoreListItemId;
                else
                {
                    scoreListItem.ScoreListItemId = temporaryScoreListItemId;
                    temporaryScoreListItemId--;
                }

                scoreListItem.ScoreListId = scoreListViewModel.ScoreListId;

                scoreList.ScoreListItems.Add(scoreListItem);
            }

            return scoreList;
        }

1 个答案:

答案 0 :(得分:0)

首先,确保您的实体正确建模。它们应该类似于:

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

    ...

    [ForeignKey("KeySignature")]
    public int KeySignatureId { get; set; }
    public virtual KeySignature KeySignature { get; set; }
}

然后,在您的操作中,您只需要使用可用的IEnumerable<SelectListItem>选项获取KeySignature

var keySignatureOptions = db.KeySignatures.Select(m => new SelectListItem
{
    Value = m.Id.ToString(),
    Text = m.Name
});

您可以将其存储在ViewBag中,或者最好使用视图模型并在其上进行设置。

然后,在您看来:

@Html.DropDownListFor(m => m.KeySignatureId, (IEnumerable<SelectListItem>)ViewBag.KeySignatureOptions)

或者

@Html.DropDownListFor(m => m.KeySignatureId, Model.KeySignatureOptions)

取决于你去的方向。

那就是它。所选值将回发到外键属性,因此您只需正常保存即可完成。