ASP.NET MVC:如何将数据插入多个表?

时间:2015-11-30 17:19:16

标签: asp.net asp.net-mvc asp.net-mvc-4

我有两张桌子(NPG_Chemical和NPG_Chemical_Synonym):

public partial class NPG_Chemical
{
    [Key]
    [Column(TypeName = "numeric")]
    public decimal NPG_Chemical_ID { get; set; }

    [StringLength(256)]
    public string Chemical { get; set; }
}

public partial class NPG_Chemical_Synonym
{
    [Key]
    [Column(TypeName = "numeric")]
    public decimal NPG_Chemical_Synonym_ID { get; set; }

    [ForeignKey("NPG_Chemical_ID")]
    [Column(TypeName = "numeric")]
    public decimal NPG_Chemical_ID { get; set; }

    [StringLength(512)]
    public string Synonym { get; set; }
}

在NPG_ChemicalController中我有类似的东西:

    [HttpPost]
    public ActionResult Create(NPG_ChemicalViewModel model)
    {
        using (var context = new NPG_Model())
        {
            var chemical = new NPG_Chemical();
            chemical.Chemical = model.NPG_Chemical.Chemical;
            context.NPG_Chemical.Add(chemical);

            var synonym = new NPG_Chemical_Synonym();
            synonym.Synonym = model.NPG_Chemical_Synonym.Synonym;
            synonym.NPG_Chemical_ID = chemical.NPG_Chemical_ID;
            context.NPG_Chemical_Synonym.Add(synonym);
            context.SaveChanges();
        }
        return View();
    }

和NPG_ChemicalViewModel:

namespace NPG_Administrative_Utility.Models
{
public class NPG_ChemicalViewModel
{
    public NPG_ChemicalViewModel()
    {
        NPG_Chemical = new NPG_Chemical();
        NPG_Chemical_Synonym = new NPG_Chemical_Synonym();
    }

    public NPG_Chemical NPG_Chemical { get; set; }
    public NPG_Chemical_Synonym NPG_Chemical_Synonym { get; set; }
}
}

当我尝试基于NPG_ChemicalViewModel创建视图时,它显示: enter image description here

任何人都可以帮我吗?

1 个答案:

答案 0 :(得分:4)

您需要一个视图模型。最简单的,您可以执行以下操作:

public class NPG_ChemicalViewModel
{
    public NPG_ChemicalViewModel()
    {
        NPG_Chemical = new NPG_Chemical();
        NPG_Chemical_Synonym = new NPG_Chemical_Synonym();
    }

    public NPG_Chemical NPG_Chemical { get; set; }
    public NPG_Chemical_Synonym NPG_Chemical_Synonym { get; set; }
}

然后,将您的操作更改为接受此操作:

public ActionResult Create(NPG_ChemicalViewModel model)

在您的视图中,您将生成以下各个属性:

@Html.EditorFor(m => m.NPG_Chemical.Chemical)

但是,仅在视图模型中包含要编辑的属性要好得多:

public class ChemicalViewModel
{
    public string Chemical { get; set; }
    public string Synonym { get; set; }
}

然后,在您的操作中,您只需将此发布的数据映射到应该去的位置:

var chemical = new NPG_Chemical();
chemical.Chemical = model.Chemical;
context.NPG_Chemical.Add(chemical);

var synonym = new NPG_Chemical_Synonym();
synonym.Synonym = model.Synonym;
synonym.NPG_Chemical_ID = chemical.NPG_Chemical_ID;
context.NPG_Chemical_Synonym.Add(synonym);

也就是说,这里的代码存在一些重大问题。首先,看起来你正在处理化学和同义词之间的一对一或一对多关系,但是现在,你没有使用外键。您应该向同义词类添加导航属性:

[ForeignKey("NPG_Chemical_ID")]
public NPG_Chemical Chemical { get; set; }

告诉Entity Framework您有关系,并且允许它根据需要自动填写ID。例如,有了这个,您现在可以简单地执行:

synonym.Chemical = chemical;

而不是直接引用ID。这样,如果在保存之前id已自动生成或未知,则仍将保留该关系。然而,如果没有它,您必须先保存chemical,在synonym上设置自动生成的ID,然后将synonym保存在单独的交易中。

其次,如果您要使用键入“数字”的键。然后,您将负责为每条记录生成唯一的数字字符串。这是一个巨大的痛苦,因为它需要在实际保存之前检查建议的ID与其他现有的记录ID。否则,您将面临主键冲突的风险。使用标准的自动增量PK或禁止至少使用GUID,可以确保发生碰撞的风险相当低。

第三,绝对不要在您的上下文中使用using。这不是什么大不了的事,因为,你只是保存而不是从数据库中读取数据,但在典型的视图中,延迟加载会让你快速做到这一点。您的上下文应该是请求范围的,作为控制器上的实例变量(因为控制器是新建的并随每个请求一起处理)或使用依赖注入。您永远不想在其他任何地方创建上下文的实例,包括操作方法。