asp.net – 实体框架:坚持在多对多添加新实体,而不是重新使用现
我有很多关系,简要地说
案例—–< CaseSubjectRelationships> —— CaseSubjects 更充分地说 在我的多对多链接表中是与主题与具体情况相关联的附加属性 – 例如开始日期,结束日期,自由文本关系(例如观察者,创建者等) 已创建实体框架数据模型 – ASP.NET 4.0版 我有一个名为CreateNewCase的方法的WCF服务,它接受一个Case对象(由Entity Framework创建的实体)作为其参数 – 它的工作是将案例保存到数据库中。 WCF服务由第三方工具调用。以下是发送的SOAP: <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Body> <CreateNewCase xmlns="http://tempuri.org/"> <c xmlns:a="http://schemas.datacontract.org/2004/07/CAMSModel"> <a:CaseSubjectsRelationships> <a:CaseSubjectsRelationship> <a:CaseSubject> <a:CRMSPIN>601</a:CRMSPIN> <a:DisplayName>Fred Flintstone</a:DisplayName> </a:CaseSubject> <a:PrimarySubject>true</a:PrimarySubject> <a:RelationToCase>Interested</a:RelationToCase> <a:StartDate>2011-07-12T00:00:00</a:StartDate> </a:CaseSubjectsRelationship> <a:CaseSubjectsRelationship> <a:CaseSubject> <a:CRMSPIN>602</a:CRMSPIN> <a:DisplayName>Barney Rubble</a:DisplayName> </a:CaseSubject> <a:RelationToCase>Observer</a:RelationToCase> <a:StartDate>2011-07-12T00:00:00</a:StartDate> </a:CaseSubjectsRelationship> </a:CaseSubjectsRelationships> <a:CaseType> <a:Identifier>Change of Occupier</a:Identifier> </a:CaseType> <a:Description>Case description</a:Description> <a:Priority>5</a:Priority> <a:QueueIdentifier>Queue One</a:QueueIdentifier> <a:Title>Case title</a:Title> </c> </CreateNewCase> </s:Body> </s:Envelope> WCF引擎将它反序列化为一个Case实体,我正确地,当我看到调试器中的一切都正确设置。 我想做的只是创建一个新的CaseSubject,如果数据库中没有指定CRMSPIN的条目(CRMSPIN是中央客户数据库的引用号) 所以,在下面的例子中,我想看看我在CaseSubjects中是否已经有一个CRMSPIN 601的一个条目,如果我这样做,我不想创建另一个(重复的)条目,而是使新的case链接到现在的主题(虽然新行将需要在CaseSubjectsRelationships中创建具体的“附加”信息,如关系等) 这是我试图这样做的.NET代码。 Public Class CamsService Implements ICamsService Public Function CreateNewCase(c As CAMSModel.Case) As String Implements ICamsService.CreateNewCase Using ctx As New CAMSEntities ' Find the case type ' Dim ct = ctx.CaseTypes.SingleOrDefault(Function(x) x.Identifier.ToUpper = c.CaseType.Identifier.ToUpper) ' Give an error if no such case type ' If ct Is Nothing Then Throw New CaseTypeInvalidException(String.Format("The case type {0} is not valid.",c.CaseType.Identifier.ToString)) End If ' Set the case type based on that found in database: ' c.CaseType = ct For Each csr In c.CaseSubjectsRelationships Dim spin As String = csr.CaseSubject.CRMSPIN Dim s As CaseSubject = ctx.CaseSubjects.SingleOrDefault(Function(x) x.CRMSPIN = spin) If Not s Is Nothing Then ' The subject has been found based on CRMSPIN so set the subject in the relationship ' csr.CaseSubject = s End If Next c.CreationChannel = "Web service" c.CreationDate = Now.Date ' Save it ' ctx.AddToCases(c) ctx.SaveChanges() End Using ' Return the case reference ' Return c.ID.ToString End Function End Class 正如你可以看到的,而不是For Each循环,我尝试根据CRMSPIN获取主题,如果我得到一些东西,那么我更新“CaseSubject”实体。 (我也尝试过csr.SubjectID = s.ID,而不是设置整个实体,并且我已经尝试设置它们! 然而,即使在ctx.SaveChanges()行上放置断点,并且查看主题的设置以及在调试器中看到它看起来不错,它总是在CaseSubjects表中创建一个新行。 我原则上可以看到这应该是正常的 – 你会看到我已经完成了相同的事情为Case类型 – 我已经选择了XML中发送的标识符,通过上下文找到具有该标识符的实体,然后更改了该案例。 CaseType到我发现的实体。当它保存时,它的工作原理和预期,没有重复的行。 我只是试图将同样的理论应用于多对多关系的一边。 以下是.edmx的一些(希望相关的)提取 <EntitySet Name="Cases" EntityType="CAMSModel.Store.Cases" store:Type="Tables" Schema="dbo" /> <EntitySet Name="CaseSubjects" EntityType="CAMSModel.Store.CaseSubjects" store:Type="Tables" Schema="dbo" /> <EntitySet Name="CaseSubjectsRelationships" EntityType="CAMSModel.Store.CaseSubjectsRelationships" store:Type="Tables" Schema="dbo" /> <AssociationSet Name="FK_CaseSubjectsRelationships_Cases" Association="CAMSModel.Store.FK_CaseSubjectsRelationships_Cases"> <End Role="Cases" EntitySet="Cases" /> <End Role="CaseSubjectsRelationships" EntitySet="CaseSubjectsRelationships" /> </AssociationSet> <AssociationSet Name="FK_CaseSubjectsRelationships_CaseSubjects" Association="CAMSModel.Store.FK_CaseSubjectsRelationships_CaseSubjects"> <End Role="CaseSubjects" EntitySet="CaseSubjects" /> <End Role="CaseSubjectsRelationships" EntitySet="CaseSubjectsRelationships" /> </AssociationSet> 编辑:CaseSubjectsRelationships对象的CaseSubject属性的属性设置器: /// <summary> /// No Metadata Documentation available. /// </summary> <XmlIgnoreAttribute()> <SoapIgnoreAttribute()> <DataMemberAttribute()> <EdmRelationshipNavigationPropertyAttribute("CAMSModel","FK_CaseSubjectsRelationships_CaseSubjects","CaseSubject")> Public Property CaseSubject() As CaseSubject Get Return CType(Me,IEntityWithRelationships).RelationshipManager.GetRelatedReference(Of CaseSubject)("CAMSModel.FK_CaseSubjectsRelationships_CaseSubjects","CaseSubject").Value End Get Set CType(Me,"CaseSubject").Value = value End Set End Property 解决方法
你没有指定你使用的上下文模型,所以我假设你使用的是默认的(即你没有一些明确的.tt文件来生成你的实体)。
所以,基本上这就是我认为正在发生的事情。 Dim ct = ctx.CaseTypes.SingleOrDefault(Function(x) x.Identifier.ToUpper = c.CaseType.Identifier.ToUpper) 这个ct在上下文中。您从服务(c)中反序列化的方法参数不在上下文中。您可以将上下文视为“对象跟踪和提取”实体,这样可以确保附件中的所有内容都可以了解任何更改(如果是新的,已删除的)。 所以,当你到达这个部分: ' Set the case type based on that found in database: ' c.CaseType = ct 在分配一些附加到不附加的东西的时刻,未连接的对象也将被拉入上下文中 – 不能有“部分”附加的实体 – 如果附加的实体,它引用的所有内容也必须被附加。所以,这是c被“拖”到上下文(隐含的)的时刻。当它进入上下文时,它将被标记为“新”,因为它不知道任何东西(它不知道它,没有更改跟踪信息…)。 所以,现在关于该对象c的所有内容都是在上下文中,当您查询上下文时: Dim s As CaseSubject = ctx.CaseSubjects.SingleOrDefault(Function(x) x.CRMSPIN = spin) 它会显示,确实有一个对象与CRMSPIN,它已经附加 – “嘿,没有必要去数据库,我已经有了! (试图聪明,避免db命中),它将返回您自己的对象。 最后,当您保存所有内容时,它将被保存,但是将附加的c和标记为“new”的所有子对象都将被插入,而不是更新。 最简单的修复将是首先从上下文查询所需的内容,然后才开始将其分配给对象的属性。另外,看看UpdateCurrentValues,也可能有帮助… (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net-mvc – ASP.NET MVC:将复杂类型绑定到选择
- asp.net – 什么是Html.AntiForgeryToken帮助函数?
- 如何在ASP.Net MVC中实现ReverseAJAX(Comet)
- asp.net – 基于角色为网站实现不同视图的最佳方法是什么?
- asp.net-mvc-4 – WepApi控制器是否应该返回viewmodels
- asp.net-mvc – 如何在json post期间发生异常时阻止asp.net
- asp.net是否可以防止SQL注入攻击
- asp.net-mvc-3 – ASP.NET MVC 3一对多无法更新桥表
- asp.net – MVP模式和会话值
- asp.net-mvc – 我应该将.edmx和生成的POCO类放在哪一层?
- asp.net-mvc – Razor MVC模型正在丢失保存操作的
- 如何在ASP.NET应用程序中避免SQL注入攻击?
- ASP.NET 2.0 – 带有tbody / thead的DataGrid
- asp.net – HTML5编辑器从微软词语粘贴时丢失格式
- asp.net-mvc-2 – ASP.NET MVC 2多个PartialView
- asp.net-mvc – 如何在ASP.NET MVC4中使用具有唯
- asp.net-core – 无法在VS2015中定位netstandard
- Singleton vs Cache ASP.NET
- asp.net-mvc – ASP.NET MVC查看引擎解析顺序
- 在MVC中使用Json.Net序列化和反序列化Json对象