C#MVC保存子项列表

时间:2011-07-30 15:08:17

标签: c# asp.net-mvc entity-framework

我是MVC和实体框架工作的新手,但我遇到了一个问题,我不知道如何解决它,一些指导更受欢迎。我正在编辑一个具有不同对象子列表的对象。我有一个工作编辑屏幕但我无法将详细信息存储回数据库。我认为问题是围绕数据库的背景,但正如我所说,我是新手。以下是我正在使用的两个班级:

public class Role
{    
    [Key]    
    public string Role { get; set; }    
    public virtual ICollection<Template> Templates { get; set; }
}
public class Template
{    
    [Key][Required]    
    public string TemplateID { get; set; }    
    [Required]    
    public string Header { get; set; }    
    [Required][DataType(DataType.MultilineText)]    
    public string Description { get; set; }    
    public virtual ICollection<CorrespondenceRole> Roles { get; set; }
}

我的上下文中也有这个

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{    
    modelBuilder.Entity<Template>()        
        .HasMany(c => c.Roles)        
        .WithMany(c => c.Templates)        
        .Map(m => m.ToTable("Template_Roles")            
            .MapLeftKey("TemplateID")            
            .MapRightKey("Role"));
}

如果我使用

public ActionResult Edit(Template ctemplate)
{
    db.Entry(ctemplate).State = EntityState.Modified;
    db.SaveChanges();
}

对模板对象的更改将记录到数据库中,但即使在db保存之前我硬编码ctemplate.roles.add(somerole),也会完全忽略对角色列表的任何更改。

但是,如果我使用

public ActionResult Edit(Template ctemplate)
{
    Template ct = db.Templates.Find(ctemplate.TemplateID);
    ct.Roles.Add(db.Roles.Find("Other Party"));
    db.Entry(ct).State = EntityState.Modified;
    db.SaveChanges();
}

“角色”将保存在数据库的模板中。所以我可以使用这个代码来找到对象,然后将所有表单字段复制到它并保存它但是当第一个选项确实有效但似乎没有保存我的列表时它看起来很长。任何意见或建议如何最好地保存对象及其相关的不同对象列表的更改?感谢。

更新 我发现这对我有用,但我不知道它是不是最好的方法。

db.Entry(ct).State = EntityState.Modified;

foreach (var entity in db.Roles.Where(cr => cr.TemplateID == ct.ID))
    db.Roles.Remove(entity);

foreach (Role cr in ct.Roles)
    db.Roles.Add(cr);

db.SaveChanges();

4 个答案:

答案 0 :(得分:1)

这对我来说也有类似的问题!!

foreach (var entity in db.Roles.Where(cr => cr.TemplateID == ct.ID)) {
                db.Entry(entity).State = EntityState.Modified;
            }

db.Roles.Remove(entity);  

答案 1 :(得分:1)

保存过程中ctemplate中是否存在对象?在你看来你也是这样做的:

foreach (var item in model.sub_object)
{
  @Html.TextBoxFor(m => item.whatever)
}

尝试这样的事情:

for (int i; i < model.sub_object.count(); i++)
{
  @Html.TextBoxFor(m => model.sub_object[i].field)
}

答案 2 :(得分:0)

如果你的问题是我认为的问题,这将解决它。问题是您需要更改列表中每个元素的EntityState。试试这个:

public ActionResult Edit(Template ctemplate)
{
    db.Entry(ctemplate).State = EntityState.Modified;
    foreach (CorrespondenceRole role in ctemplate.Roles)
    {
        //Change role State -> EntityState.Modified
    }   
    db.SaveChanges();
}

如果您的元素附加到您的上下文,它们应该保留到数据库...如果您有任何问题,请告诉我......

希望这有帮助。

答案 3 :(得分:0)

我所知道的并不是一种快速的方法。从数据库中获取模板时,您也想加载相关的角色(查看Eager Loading);这与您的问题无关,但可以节省数据库往返次数。

一旦您的角色被上下文加载,您将不得不迭代它们并修改任何已更改的内容并添加新内容并删除旧内容。它是手动的,但它确保datacontext知道您想要在对象上更改的内容。

之后,在模板上调用save应该逐渐降低到角色。