【发布时间】:2018-11-28 08:29:39
【问题描述】:
我有一个实体产品,他有一个供应商集合(这也是一个实体),我有一个合同实体,他拥有产品集合。一份合同可以包含多个产品,甚至 2 个相同的产品但使用不同的供应商。
当我尝试将第二个产品添加到我的合同中时(同样的产品,但这次 不同的供应商),EF 似乎忽略了它并且没有将它添加到 Contract.Products 集合中。没有错误,但它不会添加它。如何绕过此行为或以我可以执行此操作的方式设置我的模型/逻辑?
代码:
// THIS CONTEXT RESIDES IN A USING BLOCK
// THE updateContracts.Products ARE COMING FROM ANOTHER CONTEXT and we are receiving this entity as a parameter
// fetching the contract we are updating from database
Contract contractFromDB = ctx.Contracts.Include(s)(...)Where(p => p.ID == updateContract.ID).FirstOrDefault();
// list to populate the products we have added
List<Product> productsToAddToDBContract = new List<Product>();
foreach (Entity.Product product in updateContract.Products)
{
if (!contractFromDB.Products.Any(prod => prod.ProductName == product.ProductName))
{
// tried detaching it but didn't work
//ctx.Entry(product).State = EntityState.Detached;
productsToAddToDBContract.Add(product);
}
}
foreach (Product product in productsToAddToDBContract)
{
// get these from DB and add those to DB contract products
Product productToAdd = ctx.Products.Include(p=> p.Suppliers).Where(prod=> prod.ProductName == product.ProductName).FirstOrDefault();
if (productToAdd != null)
{
// HERE IS WHERE EF DOESN'T ADD THE SECOND PRODUCT (WHICH IS THE SAME BUT FROM ANOTHER SUPPLIER)
contractFromDB.Products.Add(productToAdd);
}
}
非常感谢。
编辑: 我试图删除从数据库中获取产品的行
Product productToAdd = ctx.Products.Include(...).Where(...).FirstOrDefault();
并且只使用我之前已经获取的产品并通过 updateContract.Products 传递,我得到 “无法定义两个对象之间的关系,因为它们附加到不同的 ObjectContext 对象。”
所以我去附加这个迭代的产品:
foreach (Product product in productsToAddToDBContract)
{
// removed this line:
// Entity.Product productToAdd = ctx.Products.Include(p=> p.Suppliers).Where(prod=> prod.ProductName == product.ProductName).FirstOrDefault();
// and added this one
ctx.Products.Attach(product);
contractFromDB.Products.Add(product);
}
然后我收到'"附加类型为'供应商'的实体失败,因为同一类型的另一个实体已经具有相同的主键值。这可能在使用'附加'方法或设置状态时发生如果图中的任何实体具有冲突的键值,则将实体设置为“未更改”或“已修改”。这可能是因为某些实体是新实体并且尚未收到数据库生成的键值。在这种情况下,请使用“添加”方法或“添加”实体状态以跟踪图表,然后将非新实体的状态设置为“未更改”或“已修改”。”请注意,该产品已附加/包含供应商,但从另一个上下文(与产品的上下文相同)。
这与我认为的产品和供应商的关系有关,或者可能因为我使用不同的上下文,我不知道,但我会进一步调查并回复。
当然,请随意以任何方式贡献:)
【问题讨论】:
-
请附上您的代码:stackoverflow.com/help/mcve
-
@Hooman,我更新了原始描述并添加了一些代码。如果我需要澄清其他任何事情,请告诉我。谢谢。
-
您添加代码了吗? :-)
-
哦,我的天(没按保存按钮,我傻了),更新了;)
-
看看this post,它可能会有所帮助......它解释了如何将新实体添加到您的 DbContext,或更新现有实体(如果已添加)。跨度>
标签: asp.net-mvc collections entity-framework-6 relational-database