Entity Framework:一对多?

Entity Framework: One-To-Many?

我正在使用 Entity Framework 处理一对多关系:

我需要从 C# 对象中插入一堆数据到我的 SQL 服务器数据库中,所以我一直在使用 Entity Framework 代码优先方法。

在我的例子中,我有一个产品有一个类别,但类别显然可以属于多个产品。

我的产品-class 看起来像这样。

    public class Product
    {
    public int ProductId { get; set; }
    public string Name { get; set; }
    public int CategoryId { get; set; }
    public Category Category { get; set; }
    }

我已经为我的类别 class 尝试了多种解决方案,包括和不包括取消注释的行,但我们开始:

    public class Category
{
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int CategoryId { get; set; }
    public string CategoryName { get; set; }
 // public ICollection<Product> Products { get; set; }
}

当插入多个具有相同类别的产品时,我违反了主键约束 - 我理解为什么会发生这种情况,但我认为 Entity Framework 会关心!

我有一长串索引,我用它从 API 中获取 XML 文件(基于该索引)。然后,我基于该 XML 文件创建了一个对象。该方法称为 GetProductFromXML:

Foreach(int index in listOfIndexes){
   Product product = GetProductFromXML(index);
   productContext.Products.Add(product);
 }
Context.SaveChanges();

每当我得到一个产品,其中的类别已经存在时,我的类别违反了主键约束-异常-table。

我想要的显然是 EF 理解的,第二个对象应该使用第一个对象的类别。

我该怎么办?我发现这是一个如此简单的操作,可以通过正常查询轻松完成,但是使用 Entity Framework 我全神贯注,我快要疯了!

希望有人能给我一个合理的答案!

您正在创建两个 个新的Category 个实例并明确地为它们提供相同的CategoryId。 (您实际上也没有 使用 任何一个实例用于您的产品,并且您从未在第二个产品上设置任何属性。我假设这些是拼写错误。)

只创建一个实例:

Category category = new Category();
category.CategoryId = 1;
category.CategoryName = "categoryA";

然后将它用于您的两个 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);

编辑: 从下面的冗长评论线程(以及更新的问题,它掩盖了新方法背后的失败代码),原来的问题仍然存在......你创建新的 Category 个实例,您应该在其中重新使用现有实例。

考虑将它们保存在您的方法之外的列表中。作为逻辑指南,如下所示:

// 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();

并且在您的 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
};