如何使用实体框架从asp.net MVC2更新数据库中的模型?
我建立ASP.NET MVC2应用程序,并使用实体框架的ORM。我有麻烦更新数据库中的对象。每次尝试entity.SaveChanges()时,EF都会在表中插入新行,而不管我想要更新,还是插入即可完成。我想(在接下来的例子等)对象的实体连接,但是后来我如何使用实体框架从asp.net MVC2更新数据库中的模型?
{"An object with a null EntityKey value cannot be attached to an object context."}
这里是我的插入和更新的简单的功能(这不是真正的汽车,但它是简单的这样来解释,虽然我不要认为这影响答案的话)......
public static void InsertOrUpdateCar(this Vehicles entity, Cars car)
{
if (car.Id == 0 || car.Id == null)
{
entity.Cars.AddObject(car);
}
else
{
entity.Attach(car);
}
entitet.SaveChanges();
}
我使用AttachTo(“汽车总动员”,汽车),甚至尝试过,但我得到了同样的异常。
任何人有这方面的经验?
如果要更新现有的记录,那么你应该有你正在为你的InsertOrUpdate方法的对象实例中的EntityKey。回到你的代码,看看你是否能找到丢失的地方。我怀疑你是向用户呈现一个表单更新此对象,然后映射响应场回一个Car对象,但你没有通过的EntityKey与它(你可能不希望它显示给用户)。
你需要做的是包括使用“隐藏”的输入型形式的关键。您可以使用Html帮助程序Html.Hidden(“Key field name”,key field value)来确保将其传递给用户表单,然后返回到Post代码。
我可以给你一个粗略的指南,但你的代码上面不给我一堆的工作。
你会想要做这样的事情:
using(Entities dataModel = new Entities())
{
if(car.Id == 0 || car.Id == null)
{
dataModel.AddToCars(car); /* There should be a generated method similar to
this that just takes a car object minus the Primary Key */
}
else
{
var selectedCar = dataModel.Cars.Where(x => x.Id == car.Id).FirstOrDefault();
if(selectedCar != null)
{
selectedCar.Name == car.Name;
// Continue updating your car stuff
}
}
dataModel.SaveChanges();
}
嗯,我之前正在考虑这种方法,但它看起来像一个“解决方法”,我想用一些更好,更传统的方法。但是,您的答案很有用。谢谢,这里投票了。 – Eedoh 2010-04-27 11:18:28
我试过这个解决方法,并且在异常消息中再次失败: “操作失败:无法更改关系,因为一个或多个外键属性是不可空的当对关系进行更改时,相关的外键属性被设置为空值,如果外键不支持空值,则必须定义新的关系,必须为外键属性指定另一个非空值,或者不相关的对象必须被删除“。 – Eedoh 2010-04-27 12:02:24
这听起来像是模式定义的问题,以及EF数据模型生成器如何从模式生成代码。我会确保你所有的关系都在edmx中定义好,并且当你在dataModel中添加/更新实体时,每个关系都有适当的数据。 这是EF的黑暗面。 – Tejs 2010-04-27 12:05:34
另一种办法,有些人可能会考虑多一点优雅是:
IContext context = ContextFactory.GetContext();
EntityRepo repo = new EntityRepo(context); //Entity Repository
OtherTableEntity y = new OtherTableEntity() //this could be some other derived value you already have
//that uniquely identifies the record (or foreign key or other value you want to update)
Int32 id = 1234; //value to update to
var z = repo.TableToUpdate.List().Where(x => x.FK_ID == y.FK_ID).FirstOrDefault();
if (z != null)
{
z.FK_ID = id;
repo.Commit();
}
把休息之前和repo.Commit();
后,有你的SQL查询窗口开放之前和之后repo.Commit()
运行选择假表。
添加条件基本上你想他们是什么。致电repo.EntityToUpdate.Add(entity)
和repo.Commit()
。
是的,我有强类型的视图,我有HttpPost方法从该窗体获取Car对象。 PK在那里,它是正确的(我已经使用隐藏字段),但EntityKey为空。我不知道为什么它丢失,也不知道在哪里:S – Eedoh 2010-04-27 11:25:16
忘记更新...这是问题所在。需要使用相同的实体密钥进行更改并保存在对象上。 – Eedoh 2010-06-09 08:31:34