[英]Entity Framework: One-To-Many?
I'm juggling with One-To-Many relationship using Entity Framework:我正在使用实体框架处理一对多关系:
I need to insert a bunch of data from C# objects into my SQL Server database, so I have been using Entity Framework with the Code First approach.我需要将一堆来自 C# 对象的数据插入到我的 SQL Server 数据库中,所以我一直在使用 Entity Framework 和 Code First 方法。
In my example, I have a product which have one category, yet categories can obviously belong to multiple products.在我的例子中,我有一个产品有一个类别,但类别显然可以属于多个产品。
My Product-class looks like this.我的产品类看起来像这样。
public class Product
{
public int ProductId { get; set; }
public string Name { get; set; }
public int CategoryId { get; set; }
public Category Category { get; set; }
}
I have tried multiple solutions for my Category class, both with and without the outcommented line but here we go:我已经为我的 Category 类尝试了多种解决方案,无论有没有注释行,但我们开始了:
public class Category
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int CategoryId { get; set; }
public string CategoryName { get; set; }
// public ICollection<Product> Products { get; set; }
}
When inserting multiple products, with the same category, I get a Primary key constraint violation - which I understand why happens, but I would think Entity Framework would care of!当插入多个具有相同类别的产品时,我会遇到主键约束违规 - 我理解为什么会发生这种情况,但我认为实体框架会关心!
I have a long list of indexes, that I use to get an XML-file (based on that index) from an API.我有一长串索引,用于从 API 获取 XML 文件(基于该索引)。 I then create an object based on that XML file.
然后我基于该 XML 文件创建一个对象。 The method is called GetProductFromXML:
该方法称为 GetProductFromXML:
Foreach(int index in listOfIndexes){
Product product = GetProductFromXML(index);
productContext.Products.Add(product);
}
Context.SaveChanges();
When ever I get a product, where the category already exists, I get an violation of primary key constraint-exception from my Category-table.每当我获得类别已经存在的产品时,我都会从我的类别表中得到主键约束异常的违反。
What I want is obviously that EF understands, that the second object should use the category from the first object.我想要的显然是 EF 明白,第二个对象应该使用第一个对象的类别。
What do I do?我该怎么办? I find this such a simple action, that would be easily done with normal querying, but with Entity Framework I wrap my head around it and I'm going nuts!
我发现这是一个如此简单的操作,可以通过普通查询轻松完成,但是使用实体框架,我将头环绕在它周围,我快要疯了!
Hope someone will give me the logic answer!希望有人能给我逻辑答案!
You're creating two new Category
instances and explicitly giving them both the same CategoryId
.您正在创建两个新的
Category
实例并明确地为它们提供相同的CategoryId
。 (You're also not actually using either instance for your products, and you never set any properties on the second product. I'm assuming these are typos.) (您实际上也没有为您的产品使用任何一个实例,并且您从未在第二个产品上设置任何属性。我假设这些是拼写错误。)
Only create one instance:只创建一个实例:
Category category = new Category();
category.CategoryId = 1;
category.CategoryName = "categoryA";
Then use it for both of your Product
instances:然后将它用于您的两个
Product
实例:
Product product = new Product();
product.ProductId = 1;
product.Name = "ProductA";
product.Category = category;
context.Products.Add(product);
Product productB = new Product();
productB.ProductId = 2;
productB.Name = "ProductB";
productB.Category = category;
context.Products.Add(productB);
Edit: From a lengthy comment thread below (and the updated question which obscures the failing code behind a new method), the original problem still remains... You're creating new Category
instances where you should be re-using existing instances.编辑:从下面的冗长评论线程(以及掩盖新方法背后失败代码的更新问题),原始问题仍然存在......您正在创建新的
Category
实例,您应该在其中重新使用现有实例。
Consider keeping them in a list outside of your method.考虑将它们保留在您的方法之外的列表中。 As a logical guide, something like this:
作为逻辑指南,如下所示:
// Note: If there are categories from previous runs of this logic
// then you should fetch them from the backing data here
var categories = new List<Category>();
foreach (int index in listOfIndexes)
{
var product = GetProductFromXML(index, categories);
productContext.Products.Add(product);
}
Context.SaveChanges();
And witin your GetProductFromXML
method:还有你的
GetProductFromXML
方法:
int id = // ... get the Product ID from your XML
string name = // ... get the Product Name from your XML
//... etc.
string categoryName = // ... get the Category Name from your XML
var category = categories.SingleOrDefault(c => c.Name == categoryName);
if (category = null)
{
// It doesn't exist yet, so add it
category = new Category();
category.Name = categoryName;
category.CategoryId = // ... whatever logic you use to determine this
categories.Add(category);
}
return new Product
{
ProductId = id,
Name = name,
// etc.
Category = category
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.