EF5 更新外键关联的列表

傲雪飞狐 2014-11-04 08:43:39
数据库有两个很简单的关键关联的表,建有如下两个Model

[Table("T_Teacher")]
public class Teacher
{
[Key]
public int Id { get; set; }

public string Name { get; set; }
public List<Student> Students { get; set; }
}

[Table("T_Student")]
public class Student
{
[Key]
public int Id { get; set; }

public string Name { get; set; }
public int TeacherId { get; set; }

[ForeignKey("TeacherId")]
public Teacher Teacher { get; set; }
}

public class SchoolContext : DbContext
{
public SchoolContext()
: base("MvcSchool")
{
}

public DbSet<Teacher> Teacher { get; set; }
public DbSet<Student> Student { get; set; }
}


建有一个View用来显示这两个Model


@model MvcSchool.Models.Teacher

@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)

<fieldset>
<legend>Teacher</legend>
<div class="editor-label">
老师
</div>
<div class="editor-field">
@Html.HiddenFor(model => model.Id)
@Html.TextBoxFor(model => model.Name)
</div>
<div class="editor-label">
学生
</div>
@for (int i = 0; i < Model.Students.Count; i++)
{
<div class="editor-field">
@Html.HiddenFor(model => Model.Students[i].Id)
@Html.TextBoxFor(model => Model.Students[i].Name)
<a href="javascript: void(0)" onclick="deleteTr(this)">删除</a>
</div>
}
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}

@section Scripts {
@Scripts.Render("~/bundles/jqueryval")

<script>
function deleteTr(e) {
$(e).parent().remove();
}
</script>
}



后台Controller代码



public ActionResult Index()
{
Teacher teacher;
using (var context = new SchoolContext())
{
teacher = context.Teacher.Include("Students").FirstOrDefault();
if (teacher == null)//如果没有数据,添加几条测试数据
{
teacher = new Teacher()
{
Name = "张老师",
Students = new List<Student>()
{
new Student() {Name = "小明"},
new Student() {Name = "小花"},
new Student() {Name = "丽丽"}
}
};
context.Teacher.Add(teacher);//这里可以正常保存
context.SaveChanges();
}
}


return View(teacher);
}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(Teacher teacher)
{
using (var context = new SchoolContext())
{
// var model = context.Teacher.Include("Students").First(m => m.Id == teacher.Id);
//TryUpdateModel(model);
context.Teacher.Attach(teacher);
context.Entry(teacher).State = EntityState.Modified;
context.SaveChanges();
}
return View(teacher);
}


然后就报这个错了~~


问题一:我要怎么写才能在前台修改model后,返回后台可以保存修改后的值
问题二:如果我在前台删除了一个学生,然后teacher的Students 列表里面只有两条数据,我要怎么做才能删除前台已经删除的学生?同时其它如果有修改,也要更新到数据库?
问题三:也是上面那个问题的综述吧,最近老是遇到前台返回一个列表要保存,大概就和分配权限一样,在前台更新用户权限之后,和数据库的对比,列表中存在的就更新,不存在的就删除,没有的新增到数据库中。我知道可能我这有做不合理,那么像这种要更新一个列表的外键关联的应该要怎么做才合理呢?
...全文
329 14 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
zujinsheng 2015-01-26
  • 打赏
  • 举报
回复
楼主竟然是个漂亮妹纸..
meduke 2015-01-26
  • 打赏
  • 举报
回复
[ForeignKey("TeacherId")] 感谢这个关联帮了我 谢谢啊
yaojunyi3725 2014-11-12
  • 打赏
  • 举报
回复
之前这种需求我做过 我的办法和3楼的类似 我是修改teacher数据 然后删掉所有这个teacher下的student 然后逐一循环sutdent列表进行添加 我对3楼提到的list集合做方法参数有疑问 没试过 从mvc几开始能够这样模型绑定了 如果楼主的办法行得通 大大简化了同时修改父子表的处理方法
引用 2 楼 q107770540 的回复:
EF里的修改 必须先获取再修改,明白?
的意思我理解他的意思是说通过ef select查询获取记录而不是通过模型绑定获取 简单模型可以用atteach获取, 有外键表的我不清楚是否可以
wyumening 2014-11-12
  • 打赏
  • 举报
回复
引用 10 楼 aoxuefeihu 的回复:
引用
参考这篇文章 http://jameszou.blog.51cto.com/2173852/1152743,有两种方法,你可以根据需要来决定采用哪种方法
非常感谢你的回答,但是你注意看我的代码的话,你会发现,里面的两种方式我都试过了
你问的不是where操作码?我给的链接中第一个方法就有讲where是如何操作的呀,至于出现错误: 定义约束引用的属性值不一致可以检查下两个外键关联的表的作为外键的字段在提交时有没有值,打断点看下,报错可能是因为这方面的原因
傲雪飞狐 2014-11-11
  • 打赏
  • 举报
回复
引用
参考这篇文章 http://jameszou.blog.51cto.com/2173852/1152743,有两种方法,你可以根据需要来决定采用哪种方法
非常感谢你的回答,但是你注意看我的代码的话,你会发现,里面的两种方式我都试过了
wyumening 2014-11-11
  • 打赏
  • 举报
回复
引用 8 楼 aoxuefeihu 的回复:
[quote=引用 3 楼 wyumening 的回复:] 错误很明显了,定义约束引用的属性值不一致,你的问题是ef修改方面的问题了,假设控制器中获得的方法参数为List<user> 那么你可以用foreach循环这个列表,用where操作符进行筛选,已经存在在数据库中的就修改,不存在的就添加,最后用SaveChanges方法保存
我现在想问的就是怎么where操作。。不知道能否讲诉清楚一些? 比如,我View获取到的Teacher如下 [/quote] 参考这篇文章 http://jameszou.blog.51cto.com/2173852/1152743,有两种方法,你可以根据需要来决定采用哪种方法
傲雪飞狐 2014-11-10
  • 打赏
  • 举报
回复
引用 3 楼 wyumening 的回复:
错误很明显了,定义约束引用的属性值不一致,你的问题是ef修改方面的问题了,假设控制器中获得的方法参数为List<user>
那么你可以用foreach循环这个列表,用where操作符进行筛选,已经存在在数据库中的就修改,不存在的就添加,最后用SaveChanges方法保存


我现在想问的就是怎么where操作。。不知道能否讲诉清楚一些?
比如,我View获取到的Teacher如下
傲雪飞狐 2014-11-10
  • 打赏
  • 举报
回复
引用 5 楼 ayanamireizero 的回复:
public Teacher Teacher { get; set; } public List<Student> Students { get; set; } 这里加上virsual试试吧....
印象中virtual是关系自动加载列表的吧?好像和保存没有关系呢。 PS,已经在代码上了virtual了,问题依旧
傲雪飞狐 2014-11-10
  • 打赏
  • 举报
回复
引用 2 楼 q107770540 的回复:
EF里的修改 必须先获取再修改,明白?
是的,我知道的哈,但是我获取之后怎么更新一个列表? 因为 List<Student> 是从View获取到的。 我并不知道这个list里面用户修改了那几个Student 在Controller中,如果先获取teacher
Teacher teacher = context.Teacher.Include("Students").First(m => m.Id == teacher.Id);
, 的确是可以获取到数据库的teacher和其对应的students,我现在需要的是,如何修改他们还能保存到数据库中
ayanamireizero 2014-11-10
  • 打赏
  • 举报
回复
public Teacher Teacher { get; set; } public List<Student> Students { get; set; } 这里加上virsual试试吧....
西南黑少 2014-11-10
  • 打赏
  • 举报
回复
错误很明显了,定义约束引用的属性值不一致,你的问题是ef修改方面的问题了,假设控制器中获得的方法参数为List<user> 那么你可以用foreach循环这个列表,用where操作符进行筛选,已经存在在数据库中的就修改,不存在的就添加,最后用SaveChanges方法保存
wyumening 2014-11-10
  • 打赏
  • 举报
回复
错误很明显了,定义约束引用的属性值不一致,你的问题是ef修改方面的问题了,假设控制器中获得的方法参数为List<user> 那么你可以用foreach循环这个列表,用where操作符进行筛选,已经存在在数据库中的就修改,不存在的就添加,最后用SaveChanges方法保存
q107770540 2014-11-10
  • 打赏
  • 举报
回复
EF里的修改 必须先获取再修改,明白?
傲雪飞狐 2014-11-10
  • 打赏
  • 举报
回复
有人帮帮忙嘛?

62,243

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧