C# 为什么我的ASP.NET MVC 4应用程序创建新实体而不是更新旧实体?
编辑:我选择的解决方案可能不是最好的,但确实有效。我将在下周检查我的代码(一旦这个项目完成),当我了解到哪里出了问题时,我会更新我的问题 我将ASP.NETMVC4框架与Entity5一起使用。下面是一些代码: 要在数据库中实例化和保存(刷新)的类:C# 为什么我的ASP.NET MVC 4应用程序创建新实体而不是更新旧实体?,c#,asp.net,asp.net-mvc,entity-framework,asp.net-mvc-4,C#,Asp.net,Asp.net Mvc,Entity Framework,Asp.net Mvc 4,编辑:我选择的解决方案可能不是最好的,但确实有效。我将在下周检查我的代码(一旦这个项目完成),当我了解到哪里出了问题时,我会更新我的问题 我将ASP.NETMVC4框架与Entity5一起使用。下面是一些代码: 要在数据库中实例化和保存(刷新)的类: public class ClassCancellation { [Key] public int Id { get; set; } public Faculty Professor
public class ClassCancellation
{
[Key]
public int Id { get; set; }
public Faculty Professor { get; set; }
public DateTime CancelledOn { get; set; }
public Course Course { get; set; }
[Required]
public ClassDate ClassCancelled { get; set; }
public Message CancellationMessage { get; set; }
[Required]
public List<Student> Students { get; set; }
}
这是一种回购方法,它将CancellationFull
转换为ClassCancellation
,然后将其保存到数据库:
public CancellationFull createClassCancellation(CancellationFull c)
{
ClassCancellation newCancellation = Mapper.Map<ClassCancellation>(c);
dc.ClassCancellations.Add(newCancellation);
dc.SaveChanges();
return Mapper.Map<CancellationFull>(dc.ClassCancellations.FirstOrDefault(cc => cc.Id == newCancellation.Id));
}
以下是其中一种回购方法的示例(其他方法非常类似):
public CourseForList getForList(int?id)
{
返回Mapper.Map(dc.Courses.FirstOrDefault(c=>c.Id==Id));
}
尝试使用Attach()
而不是Add()
Add()
用于数据库中不存在的新对象<代码>附加()用于创建与数据库中已存在的实体的关系
编辑
在没有看到您的代码的情况下,我建议附加的最佳解决方案是创建一个“存根”实例,然后将其附加到您的newCancellation
:
var existingCourse = new Course{ Id = newCancellation.ClassCancelled.Course.Id };
db.Courses.Attach(existingCourse);
newCancellation.Course = existingCourse;
我发现最简单的解决方案是在更新模型时,清除所有相关实体,然后重新添加它们 即:
问题是您有多个上下文或工作单元。将newCancellation添加到dc上下文时,它还会在对象图中添加dc上下文中未跟踪的任何相关实体。我认为你最好的选择是:
dc.ClassCancellations.Add(newCancellation);
dc.Entry(newCancellation.Course).State = EntityState.Unchanged;
dc.Entry(newCancellation.Faculty).State = EntityState.Unchanged;
有关说明和其他选项,请参阅
在我看来,EF应该识别具有自动编号键的实体,而不是在指定键的情况下插入它们。我已经编辑了您的标题。请看“”,其中的共识是“不,他们不应该”。谢谢约翰。我不熟悉这个^。^那些教员和课程对象来自哪里?它们是否已连接?教员和课程对象从数据库中检索,然后映射到其他repo方法中的viewmodels。编辑:试图澄清一点-。-Mapper.Map是否创建了一个具有一些DBs属性的全新对象,但没有必要的EF属性来说明它已经存在于DB中?因此,它一直在添加新对象。
newCancellation
对象是全新的,需要保存。它的一些属性引用了数据库中已经存在的对象。感谢您让我注意到Attach()
,这可能会帮助我解决另一个问题。您能否显示教员和课程对象的设置位置?它们是在最初通过实体dbcontext
对数据库进行种子设定时创建的。我将添加代码,在viewmodel表单中检索它们。嘿,除非你真的认为这会有帮助。我会粘贴整个内容,但是这个页面会变得很长:p这对我不起作用。它引发异常(InvalidOperationException
),说明保存或接受更改失败,因为“IntAssignment.Models.Faculty”类型的多个实体具有相同的主键值。
public CourseForList getForList(int? id)
{
return Mapper.Map<CourseForList>(dc.Courses.FirstOrDefault(c => c.Id == id));
}
dc.ClassCancellations.Attach(newCancellation);
dc.SaveChanges();
var existingCourse = new Course{ Id = newCancellation.ClassCancelled.Course.Id };
db.Courses.Attach(existingCourse);
newCancellation.Course = existingCourse;
newCancellation.Students.Clear();
foreach ( var student in students )
{
newCancellation.Students.Add(student);
}
dc.ClassCancellations.Add(newCancellation);
dc.Entry(newCancellation.Course).State = EntityState.Unchanged;
dc.Entry(newCancellation.Faculty).State = EntityState.Unchanged;