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
};
我正在使用 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
};