在 EF Core 中合并冲突
Merge conflict in EF Core
我想更改项目中的模型和 tables。我现在有一些模型:Product、ProductType、ProductComposition、ProductSize、ShoppingCart。
Product有FK(ProductType, ProductTypeId),其他有FK到Product(ProductId, Product)
我还有一个带有 Initialize 方法的 InitData.cs 文件,我在 table 中添加了一些东西,所以我有一些事情要做。但是问题来了:
Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details. ---> System.Data.SqlClient.SqlException:
The MERGE statement conflicted with the FOREIGN KEY constraint "FK_Products_ProductTypes_ProductTypeId". The conflict occurred in database "clothesstoredb", table "dbo.Products", column 'Id'.
The statement has been terminated.
我不太清楚为什么会这样,可能是我FK的模型做错了什么?我刚学,所以有点难以理解。
此外,我的 Guid cookie 生成方法也不知何故崩溃了。我看不出问题出在哪里,但是 cookie 是空的,我无法添加 GUID,即使它在我更改模型之前工作。我觉得这很奇怪,因为我根本没有改变 Startup.cs。
这是我的模型。
{
public int Id { get; set; }
public string Image { get; set; }
public string BrandName { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Material { get; set; }
public int Price { get; set; }
public int ProductTypeId { get; set; }
public ProductType ProductType { get; set; }
}
public class ProductType
{
public int Id { get; set; }
public string Description { get; set; }
}
public class ProductComposition
{
public int Id { get; set; }
public int? Cotton { get; set; }
public int? Denim { get; set; }
public int? Leather { get; set; }
public int? Polyester { get; set; }
public int? Nylon { get; set; }
public int? Elastane { get; set; }
public int ProductId { get; set; }
public Product Product { get; set; }
}
public class ProductSize
{
public int Id { get; set; }
public bool S { get; set; }
public bool M { get; set; }
public bool L { get; set; }
public bool XL { get; set; }
public bool XXL { get; set; }
public int ProductId { get; set; }
public Product Product { get; set; }
}
public class ShoppingCart
{
public int Id { get; set; }
public string Guid{ get; set; }
public int Quantity { get; set; }
public int ProductId { get; set; }
public Product Product { get; set; }
}
这是我的 InitData.cs,主要问题出现在哪里:
public static class InitData
{
public static void Initialize(ClothesContext context)
{
if (!context.Products.Any())
{
context.Products.AddRange(
new Product
{
Id = 1,
BrandName = "Vans",
Name = "Лонгслив OTW RAGLAN",
Image = "https://a.lmcdn.ru/img600x866/V/A/VA984EMCRY32_1833129_1_v2.jpg",
Description = "Хлопковый лонгслив от Vans решен в контрастной бело-черной цветовой гамме. " +
"Детали: прилегающий крой, рукав 3/4, округлый вырез горловины, стильный принт на фронтальной стороне.",
Material = "Хлопок - 100%",
Price = 2151,
ProductTypeId = 3
},
new Product
{
BrandName = "United Colors of Benetton",
Name = "Рубашка",
Price = 2510,
Description = "Рубашка United Colors of Benetton выполнена из тонкого, приятного на ощупь материала. Модель приталенного кроя. " +
"Детали: отложной воротник, планка и манжеты на пуговицах, слегка удлиненная спинка.",
Image = "https://a.lmcdn.ru/img600x866/U/N/UN012EMVWY79_5145481_1_v4.jpg",
Material = "Хлопок - 68%, Нейлон - 28%, Эластан - 4%",
ProductTypeId = 4
},
new Product
{
BrandName = "Jordan",
Name = "Толстовка M J JUMPMAN FLEECE FZ",
Price = 5690,
Description = "Толстовка от спорт-бренда выполнена из хлопкового трикотажа. Модель прямого кроя. " +
"Детали: регулируемый капюшон, два кармана, манжеты и низ на резинки, застежка на молнию.",
Image = "https://a.lmcdn.ru/img600x866/J/O/JO025EMFNEV0_9024380_1_v1_2x.jpg",
Material = "Хлопок - 80%, Полиэстер - 20%",
ProductTypeId = 2
},
new Product
{
BrandName = "Burton Menswear London",
Name = "Футболка",
Price = 1430,
Description = "Футболка из 100% хлопка.",
Image = "https://a.lmcdn.ru/img600x866/B/U/BU014EMFIHX0_8767196_1_v1.jpg",
Material = "Хлопок - 100%",
ProductTypeId = 1
}
);
}
if (!context.ProductTypes.Any())
{
context.ProductTypes.AddRange(
new ProductType {
Description = "Футболки"
},
new ProductType
{
Description = "Худи"
},
new ProductType
{
Description = "Лонгсливы"
},
new ProductType
{
Description = "Рубашки"
}
);
}
if (!context.ProductSizes.Any())
{
context.ProductSizes.AddRange(
new ProductSize
{
ProductId = 1,
XL = false,
L = true,
M = false,
S = false,
XXL = true
},
new ProductSize
{
ProductId = 2,
XL = true,
L = true,
M = true,
S = false,
XXL = true
},
new ProductSize
{
ProductId = 3,
XL = true,
L = false,
M = false,
S = false,
XXL = true
},
new ProductSize
{
ProductId = 4,
XL = false,
L = true,
M = false,
S = false,
XXL = true
}
);
}
if (!context.ProductCompositions.Any())
{
context.ProductCompositions.AddRange(
new ProductComposition
{
ProductId = 1,
Cotton = 100
},
new ProductComposition
{
ProductId = 2,
Cotton = 68,
Nylon = 28,
Elastane = 4
},
new ProductComposition
{
ProductId = 3,
Cotton = 80,
Polyester = 20
},
new ProductComposition
{
ProductId = 4,
Cotton = 100
}
);
}
context.SaveChanges();
}
}
我期望数据库结构可以通过 ProductTypeId 设置衣服类型,通过在 Size table 中使用布尔值设置尺码,并使用 int 设置 Composition?值。
您的 MERGE 语句试图插入一条在父 table 中没有相应记录的记录,因此出现错误。你需要确保
您需要先为子实体(如 ProductType
table)播种,然后使用 context.SaveChanges()
保存数据 firstly.Then 您为 Product
播种具有现有 ProductTypeId
的实体并且还记得使用 context.SaveChanges()
.
此外,如果您想手动为 Key
提供一个值,您需要在该字段上添加以下属性:
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id { get; set; }
否则会增加为1,2...
我想更改项目中的模型和 tables。我现在有一些模型:Product、ProductType、ProductComposition、ProductSize、ShoppingCart。 Product有FK(ProductType, ProductTypeId),其他有FK到Product(ProductId, Product)
我还有一个带有 Initialize 方法的 InitData.cs 文件,我在 table 中添加了一些东西,所以我有一些事情要做。但是问题来了:
Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details. ---> System.Data.SqlClient.SqlException:
The MERGE statement conflicted with the FOREIGN KEY constraint "FK_Products_ProductTypes_ProductTypeId". The conflict occurred in database "clothesstoredb", table "dbo.Products", column 'Id'.
The statement has been terminated.
我不太清楚为什么会这样,可能是我FK的模型做错了什么?我刚学,所以有点难以理解。 此外,我的 Guid cookie 生成方法也不知何故崩溃了。我看不出问题出在哪里,但是 cookie 是空的,我无法添加 GUID,即使它在我更改模型之前工作。我觉得这很奇怪,因为我根本没有改变 Startup.cs。
这是我的模型。
{
public int Id { get; set; }
public string Image { get; set; }
public string BrandName { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Material { get; set; }
public int Price { get; set; }
public int ProductTypeId { get; set; }
public ProductType ProductType { get; set; }
}
public class ProductType
{
public int Id { get; set; }
public string Description { get; set; }
}
public class ProductComposition
{
public int Id { get; set; }
public int? Cotton { get; set; }
public int? Denim { get; set; }
public int? Leather { get; set; }
public int? Polyester { get; set; }
public int? Nylon { get; set; }
public int? Elastane { get; set; }
public int ProductId { get; set; }
public Product Product { get; set; }
}
public class ProductSize
{
public int Id { get; set; }
public bool S { get; set; }
public bool M { get; set; }
public bool L { get; set; }
public bool XL { get; set; }
public bool XXL { get; set; }
public int ProductId { get; set; }
public Product Product { get; set; }
}
public class ShoppingCart
{
public int Id { get; set; }
public string Guid{ get; set; }
public int Quantity { get; set; }
public int ProductId { get; set; }
public Product Product { get; set; }
}
这是我的 InitData.cs,主要问题出现在哪里:
public static class InitData
{
public static void Initialize(ClothesContext context)
{
if (!context.Products.Any())
{
context.Products.AddRange(
new Product
{
Id = 1,
BrandName = "Vans",
Name = "Лонгслив OTW RAGLAN",
Image = "https://a.lmcdn.ru/img600x866/V/A/VA984EMCRY32_1833129_1_v2.jpg",
Description = "Хлопковый лонгслив от Vans решен в контрастной бело-черной цветовой гамме. " +
"Детали: прилегающий крой, рукав 3/4, округлый вырез горловины, стильный принт на фронтальной стороне.",
Material = "Хлопок - 100%",
Price = 2151,
ProductTypeId = 3
},
new Product
{
BrandName = "United Colors of Benetton",
Name = "Рубашка",
Price = 2510,
Description = "Рубашка United Colors of Benetton выполнена из тонкого, приятного на ощупь материала. Модель приталенного кроя. " +
"Детали: отложной воротник, планка и манжеты на пуговицах, слегка удлиненная спинка.",
Image = "https://a.lmcdn.ru/img600x866/U/N/UN012EMVWY79_5145481_1_v4.jpg",
Material = "Хлопок - 68%, Нейлон - 28%, Эластан - 4%",
ProductTypeId = 4
},
new Product
{
BrandName = "Jordan",
Name = "Толстовка M J JUMPMAN FLEECE FZ",
Price = 5690,
Description = "Толстовка от спорт-бренда выполнена из хлопкового трикотажа. Модель прямого кроя. " +
"Детали: регулируемый капюшон, два кармана, манжеты и низ на резинки, застежка на молнию.",
Image = "https://a.lmcdn.ru/img600x866/J/O/JO025EMFNEV0_9024380_1_v1_2x.jpg",
Material = "Хлопок - 80%, Полиэстер - 20%",
ProductTypeId = 2
},
new Product
{
BrandName = "Burton Menswear London",
Name = "Футболка",
Price = 1430,
Description = "Футболка из 100% хлопка.",
Image = "https://a.lmcdn.ru/img600x866/B/U/BU014EMFIHX0_8767196_1_v1.jpg",
Material = "Хлопок - 100%",
ProductTypeId = 1
}
);
}
if (!context.ProductTypes.Any())
{
context.ProductTypes.AddRange(
new ProductType {
Description = "Футболки"
},
new ProductType
{
Description = "Худи"
},
new ProductType
{
Description = "Лонгсливы"
},
new ProductType
{
Description = "Рубашки"
}
);
}
if (!context.ProductSizes.Any())
{
context.ProductSizes.AddRange(
new ProductSize
{
ProductId = 1,
XL = false,
L = true,
M = false,
S = false,
XXL = true
},
new ProductSize
{
ProductId = 2,
XL = true,
L = true,
M = true,
S = false,
XXL = true
},
new ProductSize
{
ProductId = 3,
XL = true,
L = false,
M = false,
S = false,
XXL = true
},
new ProductSize
{
ProductId = 4,
XL = false,
L = true,
M = false,
S = false,
XXL = true
}
);
}
if (!context.ProductCompositions.Any())
{
context.ProductCompositions.AddRange(
new ProductComposition
{
ProductId = 1,
Cotton = 100
},
new ProductComposition
{
ProductId = 2,
Cotton = 68,
Nylon = 28,
Elastane = 4
},
new ProductComposition
{
ProductId = 3,
Cotton = 80,
Polyester = 20
},
new ProductComposition
{
ProductId = 4,
Cotton = 100
}
);
}
context.SaveChanges();
}
}
我期望数据库结构可以通过 ProductTypeId 设置衣服类型,通过在 Size table 中使用布尔值设置尺码,并使用 int 设置 Composition?值。
您的 MERGE 语句试图插入一条在父 table 中没有相应记录的记录,因此出现错误。你需要确保
您需要先为子实体(如 ProductType
table)播种,然后使用 context.SaveChanges()
保存数据 firstly.Then 您为 Product
播种具有现有 ProductTypeId
的实体并且还记得使用 context.SaveChanges()
.
此外,如果您想手动为 Key
提供一个值,您需要在该字段上添加以下属性:
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id { get; set; }
否则会增加为1,2...