【发布时间】:2011-11-20 21:11:59
【问题描述】:
我有一个非常令人沮丧的问题(无论如何对我来说):
我有一个简单的场景,我有一个产品实体和一个组合产品实体。它们之间是多对多的关系,所以一个Product可以属于多个CombinedProduct,一个CombinedProduct可以包含多个product。
我首先创建一个产品并将其保存到数据库中。稍后我创建了一个 CombinedProduct 并添加了这个产品。当我尝试保存此 CombinedProduct 时,Entity Framework 将产品实体再次添加到数据库中,而不仅仅是添加关系......这真的让我发疯了。
我已经尝试在保存之前再次将产品附加到上下文,但实体抱怨它已经有一个具有相同密钥的产品...
您可以在下面找到所有这些的代码(简化和代码剥离):
产品实体
Public Class SingleProduct
Property SingleProductId As Integer
Property CombinedProducts As ICollection(Of CombinedProduct)
End Class
组合产品
Public Class CombinedProduct
Public Sub New()
Me.Products = New HashSet(Of SingleProduct)()
End Sub
Property CombinedProductId As Integer
Property Products As ICollection(Of SingleProduct)
End Class
多对多关系定义
Protected Overrides Sub OnModelCreating(modelBuilder As DbModelBuilder)
modelBuilder.Entity(Of CombinedProduct)().
HasMany(Function(c) c.Products).
WithMany(Function(p) p.CombinedProducts).
Map(Sub(m)
m.ToTable("CombinedProductSingleProducts")
m.MapLeftKey("SingleProductId")
m.MapRightKey("CombinedProductId")
End Sub)
End Sub
用于保存的代码
Using myDataContext As New DataContext
myDataContext.CombinedProducts.Add(product)
myDataContext.SaveChanges()
End Using
已尝试在保存前附加,但没有成功
For Each prd In product.Products
If myDataContext.Entry(prd).State = EntityState.Detached Then
myDataContext.SingleProducts.Attach(prd)
End If
Next
我发现的一个“解决方案”是在保存、清除产品列表并再次从数据库中获取产品并将其添加到 CombinedProduct 之前,但这几乎不是解决方案。
希望有人能帮助我,这让我发疯了! (我使用 Entity Framework 4.1,代码优先)
编辑
添加产品:这是在它自己的数据上下文中以其他形式完成的:
Using myDataContext As New DataContext
myDataContext.SingleProducts.Add(singleProduct)
myDataContext.SaveChanges()
End Using
组合产品创建:
Dim myCombinedProduct = New CombinedProduct
myCombinedProduct.Products.Add(product)
我添加的产品首先在它自己的数据上下文中再次获取:
Using myDataContext As New DataContext
Return myDataContext.Products.FirstOrDefault(Function(p) p.ProductId = id)
End Using
编辑
完整的故事希望更清楚:
我有一个带有两种形式的 winforms 应用程序:一种用于管理产品,另一种用于管理组合产品。该应用程序是 N 层(用户层、业务层和数据层)。
在管理您的产品的表单上,您可以简单地添加/更新/删除产品。在这种形式上,一切正常。
组合的产品形式是另一回事:
- 在加载表单时,我从数据库中检索所有产品,通过业务和数据层。在数据层中检索产品的函数有它自己的 DataContext(使用块)。此函数返回一个 iEnumerable 产品。
- 检索到的产品作为对象添加到多个组合框中。
- 您选择要添加到组合产品中的产品,方法是选择它们
- 保存时,我在用户层创建了一个新的 CombinedProduct 实体,从组合框中检索产品对象并将它们添加到新的 CombinedProduct 对象中
- 我将 CombinedProduct 对象发送到我执行许多业务规则的业务层
- 如果一切顺利,combinedProduct 将发送到数据层,我尝试将其再次保存在它自己的数据上下文中(使用块)。
所以我有多个 DataContexts,因为它们在数据层中生存和死亡。
希望这能让事情更清楚一点。
【问题讨论】:
-
“我首先创建一个产品并将其保存到数据库中。稍后我创建一个组合产品并添加此产品。” 你能展示这个过程的代码吗?这是真正重要的代码 sn-p。
-
添加产品这是在它自己的数据上下文中以其他形式完成的
Using myDataContext As New DataContext myDataContext.SingleProducts.Add(singleProduct) myDataContext.SaveChanges() End Using组合产品创建Dim myCombinedProduct = New CombinedProduct myCombinedProduct.Products.Add(product)我添加的产品首先在它自己的数据上下文中再次获取 ` Using myDataContext As New DataContext Return myDataContext.Products.FirstOrDefault(Function(p) p.ProductId = id) End Using ` -
您可以编辑您的问题以获取此类详细信息(问题下方的“编辑”链接)。我现在已经完成了,就像下次的信息一样。
标签: entity-framework entity-framework-4.1