添加到 ObjectContext 的错误对象 (_addedEntityStore)
我的 asp.net MVC 应用程序中有一个向导,它基于 此 SoG - RESTFUL 向导指南。
为了理解这个问题我首先解释一下下面的情况。为此,我将使用一个虚拟情况,我们尝试创建一个具有地址的人。再次强调,这只是一个虚拟情况!
情况
开始时,使用向导创建和保存的对象(人)被创建为空白对象(人),并将在向导阶段填充'。在各个向导步骤之间,人员对象存储在 SESSION 中并使用密钥检索。该对象与子对象有关系。例如,地址。该地址可以使用向导中的下拉菜单从数据库中检索,也可以在向导本身中创建。这意味着在创建时我将创建一个空地址对象,因此我们进行以下初始化:
Persons p = new Persons();
p.Addressess = new Addressess()
该对象被传递到 FormViewModel 并在向导表单中使用。这里我有一个下拉菜单,可以选择:(1)*为人员创建新地址”,它使用通常的方式(TryUpdateModel())和(2)“地址x”用数据填充传递的空地址对象,从数据库
中选择一个地址将在控制器 POST 方法中从数据库中检索该对象并将其耦合到 person.Addresses 代码中:
p.Addresses = repository.GetContactByID(id);
问题
一切 。在运行向导页面时工作正常。当我在最终概述中调用 savechanges() 时,会正确显示要添加的完整对象(所选的人员信息 + 地址信息)。通过),也会将空地址保存到数据库中。
repository.SaveChanges();
这将尝试向数据库添加空地址,这将引入 ModelState 错误,因为地址有一些不可为空的地址,这些地址未为空对象设置
。主意 ** 我目前的想法是,当我第一次将它耦合到 person.Addresses 时,在开始时为空白对象创建的空对象以某种方式置于添加状态(对象上下文)。可以这样吗?做我想做的事的正确方法是什么?我可以手动从对象上下文 _addedEntityStore 中删除内容吗?
其他信息
在下拉列表中选择地址将强制表单。提交到 POST 控制器方法,然后它将使用更新的选择信息和重新加载表单新地址的输入字段(如果需要新地址)设置为“禁用”,因此您只能看到信息,但无法编辑现有地址。
此外,仅使用保存在 SESSION 中的一个 objectContext。
I have a wizard in my asp.net MVC application which is built upon this SoG - RESTFUL wizard guide.
In order to understand the problem I will first explain the situation below. For this I will use a dummy situation, we try to create a person with an address. Again, this is just a dummy situation!
The situation
At start, the object (person) to be created and saved using the wizard is created as a blank object (person) and will be filled during the wizard 'stage'. In between the various wizard steps the person object is stored in the SESSION and retrieved with a key. This object has a relation with a sub-object. For example, an address. This address can either be retrieved from a DB using a dropdown-menu in the wizard or can be created in the wizard itself. This means that at creation I will create an empty address-object so we have the following initialization:
Persons p = new Persons();
p.Addressess = new Addressess()
This object is passed to the FormViewModel and used in the Wizard Form. Here I have a drop-down enabling to choose: (1) *create new address for person", which fills the passed empty-address object with data using the usual ways (TryUpdateModel()) and (2) "address x", addresses to select from your DB.
Selecting one of the addresses in the dropdown will, in the controller POST method, retrieve this object from DB and couple it to the person.Addresses. In code:
p.Addresses = repository.GetContactByID(id);
The problem
Everything works fine while running through the wizard pages. The problem occurs when I call the savechanges(). While in a final overview the complete object to be added is shown correctly (person info + address info as selected / passed), also an empty address is saved to the database.
repository.SaveChanges();
This will try to add an empty Addresses to the DB which will introduce a ModelState error since Addresses have some non-nullable's which are not set for the empty object.
** My current idea **
My current thinking is that the empty object created at start for the blank object is somehow placed in added state (objectcontext) when I first couple it to person.Addresses. Can this be the case? What would be the correct way to do what I want? Can I manually delete things from the object context _addedEntityStore ?
Additional Info
Selection of an address in the dropdown will force a form.submit to the POST controller method and consecutively it will reload the form with updated selection info and the input fields for the new address (in case a new one is wanted) set to "disabled" so you only see the info but cannot edit an existing address.
Also, only one objectContext is used which is saved in the SESSION.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当您首次创建
Persons
对象时,您不能将p.Addressess
保留为 null,并且仅在向导中选择新地址时才添加新地址,有什么原因吗?(顺便说一句,为什么奇怪的复数形式?它们有一个地址还是多个地址?)
您将遇到的另一个问题是您将在一个上下文中加载现有地址并将它们保存在另一个上下文中(假设您正在使用每个请求上下文的方法) - 您需要将现有地址从加载的一个上下文中分离出来,并将它们附加到用于在向导结束时保存人员的上下文。
在会话状态中包含单独的
AddressNew
和AddressExisting
对象(其中一个为 null)可能会更容易。最后,如果存在AddressNew
,请将其添加到Person
并保存更改。如果存在AddressExisting
,请将其附加到上下文,将其添加到Person
并保存更改。Any reason you can't just leave
p.Addressess
as null when you first create aPersons
object and only add a new Address if that's what they select in the wizard?(And BTW why the odd pluralization? Do they have one address or several?)
The other issue you will encounter is that you will be loading existing addresses in one context and saving them in another (assuming you are using a context per request approach) - you'll need to detach the existing addresses from one context they were loaded in and attach them to the context used to save Person at the end of the wizard.
It might be easier to include a separate
AddressNew
and anAddressExisting
object in the Session state (one or the other is null). At the end, ifAddressNew
is present, add it to thePerson
and save changes. IfAddressExisting
is present, attach it to the context, add it to thePerson
and save changes.尽管 Hightechrider 对于每个工作单元使用对象上下文是正确的,但我发布了我现在使用的简单解决方案。当您以某种方式(强制、选择等)将对象上下文存储在 SESSION 中时,您只需通过调用即可解决上述问题:
这将从上下文中分离旧对象(尚未保存到数据库)。分离后,附加您想要链接的新对象。
不过,如果您需要这样做并且有时间和能力,我确实建议重写您的向导:)。
编辑
请注意,分离仅分离提供的对象,而不分离其相关对象(!)。
Although Hightechrider is right about using an object context for every unit of work I post the simple solution I used for now. When you somehow (forced, chosen, whatever) have your object context stored in SESSION you can solve the above problem simply by calling:
Which will detach the old object from the context (not saved yet to DB). And after detaching, attach the new object you want to have it linked to.
Though I do recommend rewriting your wizard if you need to do this and have the time and power :).
edit
note that Detach only detaches the object supplied, not its related objects (!).