简体   繁体   English

实体框架:一对多?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM