【发布时间】:2020-04-13 11:06:04
【问题描述】:
我刚开始使用 C#、Linq 和 MSSQLSERVER 使用 Codefirst-Approach 制作我的第一个项目,并在尝试插入包含对另一个表中已有元素的引用的新 DB 条目时遇到问题。
InnerException {“违反主键约束“PK_dbo.Manufacturers”。无法在对象“dbo.Manufacturers”中插入重复键。重复键值为 (1d262e43-b9b6-4752-9c79-95d955d460ab)。\r\n语句已终止。"} System.Exception {System.Data.SqlClient.SqlException}
我将问题分解为一个简单的项目,并将其上传到共享中。 我的数据结构包含一个类。产品链接到制造商对象和可能的供应商列表。
public class Product
{
[Key]
public Guid Id { get { return _id; } set { _id = value; } }
private Guid _id = Guid.NewGuid();
public string Name { get; set; }
public Manufacturer Manuf { get; set; }
public List<Supplier> PossibleSupplier { get { return _possibleSupplier; } set { _possibleSupplier = value; } }
private List<Supplier> _possibleSupplier = new List<Supplier>();
}
public class Supplier
{
[Key]
public Guid Id { get { return _id; } set { _id = value; } }
private Guid _id = Guid.NewGuid();
public string Name { get; set; }
}
public class Manufacturer
{
[Key]
public Guid Id { get { return _id; } set { _id = value; } }
private Guid _id = Guid.NewGuid();
public string Name { get; set; }
}
我现在生成 2 个产品。
- 两种产品均由同一制造商生产。
- PossibleSuppliers 列表中也包含相同的供应商
private void GenerateProducts()
{
Manufacturer manufactuer1 = new Manufacturer() { Name = "mainManuf 1" };
Supplier supplier1 = new Supplier() { Name = "first Supplier" };
Supplier supplier2 = new Supplier() { Name = "second Supplier" };
Product firstProduct = new Product() { Name = "Product 1", Manuf = manufactuer1, PossibleSupplier = new List<Supplier>() { supplier1, supplier2 } };
Product secondProduct = new Product() { Name = "Product 2", Manuf = manufactuer1, PossibleSupplier = new List<Supplier>() { supplier1 } };
productList_ = new List<Product>() { firstProduct, secondProduct };
}
以下方法用于存储/更新数据库条目
public static class DbHandler
{
public static bool StoreProduct(Product product)
{
using (ProductDbContext dbObject = new ProductDbContext())
{
try
{
dbObject.Products.AddOrUpdate(product);
dbObject.SaveChanges();
}
catch (Exception ex)
{
//
return false;
}
}
return true;
}
}
public class ProductDbContext : DbContext
{
public ProductDbContext()
{
Database.SetInitializer<ProductDbContext>(new DropCreateDatabaseAlways<ProductDbContext>());
this.Database.Connection.ConnectionString = sqlConnection.ConnectionString;
}
public DbSet<Product> Products { get; set; }
public DbSet<Supplier> Suppliers { get; set; }
public DbSet<Manufacturer> Manufacturers { get; set; }
private static SqlConnectionStringBuilder sqlConnection = new SqlConnectionStringBuilder()
{
DataSource = "localhost\\MSSQLSERVER2019", // update me
UserID = "", // update me
Password = "", // update me
InitialCatalog = "ProductDb",
IntegratedSecurity = true
};
}
可以毫无问题地插入第一个产品。
此外,插入具有独特制造商和供应商的其他产品也不会出现问题。 **所以我没有主键唯一性的问题。 **
当我想将具有外键的新条目添加到现有条目时,我只会收到此错误。
使用dbObject.Products.AddOrUpdate(product); 而不是dbObject.Products.Add(product); 并没有解决我的问题。
在添加第二个产品之前,我也无法删除制造商条目,因为这会违反我第一个产品的外键......
我通过为 ManufacturerId 添加附加属性找到了 possible solution for manufacturer
public Guid? ManuId { get; set; }
[ForeignKey("ManuId")]
public Manufacturer Manuf { get; set; }
到我的数据对象,但我不知道如何使用我的 List PossibleSupplier 做到这一点??
有人能把我推向正确的方向吗?
!!非常感谢您的快速回放!!
我已将我的 DataStructure 更新如下:
public class Product
{
[Key]
public Guid Id { get { return _id; } set { _id = value; } }
private Guid _id = Guid.NewGuid();
public string Name { get; set; }
public virtual Manufacturer Manufacturer { get; set; }
public virtual ICollection<Supplier> PossibleSupplier { get; set; }
}
public class Supplier
{
[Key]
public Guid Id { get { return _id; } set { _id = value; } }
private Guid _id = Guid.NewGuid();
public string Name { get; set; }
[ForeignKey("Product")]
public Guid ProductId { get; set; }
public virtual Product Product { get; set; }
}
public class Manufacturer
{
[Key]
public Guid Id { get { return _id; } set { _id = value; } }
private Guid _id = Guid.NewGuid();
public string Name { get; set; }
[ForeignKey("Product")]
public Guid ProductId { get; set; }
public virtual ICollection<Product> Product { get; set; }
}
但我在尝试插入第二个条目时仍然收到“违反主键约束 'PK_dbo.Manufacturers'。无法插入重复键...”错误。
我已经附上了DB looks in SQL-Server
【问题讨论】:
-
链接到测试项目SqlTestporject
-
我认为您需要在 Manufacturer 和 Product 之间建立一对多的关系,将虚拟 ICollection
Products 添加到 Manufacturer 类。你检查过 EF 为这两者生成了什么样的关系吗? -
我也把新项目上传到上面的link了。
标签: c# sql linq code-first