Entity Framework - Code First - 外键约束
Entity Framework - Code First - Foreign Key Constraint
我正在使用 entity framework 的代码优先方法开发数据库。
我想在几个表之间使用外键,例如:
public class Producer
{
[Key]
public int Id { get; set; }
[Required]
[StringLength(254)]
public string Name { get; set; }
}
然后另一个文件模型被简化为
public class Product
{
[Key]
public int Id { get; set; }
[Required]
[StringLength(254)]
public string Name { get; set; }
}
我想要的是在产品上定义一个 ProducerId 字段并将其 link 到 Producers ID 字段,但我不知道如何告诉它 model/table 它的 link 到。
谁能澄清一下?我认为根据我阅读的内容,我似乎需要使 ID 字段更具描述性,EF 会找到该字段,ProductId 用于 Products Id 字段 - 但我仍然不肯定它会跨表工作。
这是正确的还是我错过了什么?
编辑:
我尝试了下面的第一个答案,但使用了比这两个更多的表,并得到了这个错误:
fail: Microsoft.EntityFrameworkCore.Database.Command[20102]
Failed executing DbCommand (46ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE `Product` (
`ProductId` int NOT NULL AUTO_INCREMENT,
`ProducerId` int NOT NULL,
`ProductCategoryId` int NOT NULL,
`ProductStyleId` int NOT NULL,
`Name` varchar(254) NULL,
`Year` datetime NOT NULL,
`CreatedAt` datetime NOT NULL,
`CategoryId` int NOT NULL,
`StyleId` int NOT NULL,
`Image` varbinary(4000) NULL,
`TastingNotes` text NULL,
`Description` text NULL,
PRIMARY KEY (`ProductId`),
CONSTRAINT `FK_Product_Producers_ProducerId` FOREIGN KEY (`ProducerId`) REFERENCES `Producers` (`ProducerId`) ON DELETE CASCADE,
CONSTRAINT `FK_Product_ProductCategory_ProductCategoryId` FOREIGN KEY (`ProductCategoryId`) REFERENCES `ProductCategory` (`ProductCategoryId`) ON DELETE CASCADE,
CONSTRAINT `FK_Product_ProductStyle_ProductStyleId` FOREIGN KEY (`ProductStyleId`) REFERENCES `ProductStyle` (`ProductStyleId`) ON DELETE CASCADE
);
Failed executing DbCommand (46ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE `Product` (
`ProductId` int NOT NULL AUTO_INCREMENT,
`ProducerId` int NOT NULL,
`ProductCategoryId` int NOT NULL,
`ProductStyleId` int NOT NULL,
`Name` varchar(254) NULL,
`Year` datetime NOT NULL,
`CreatedAt` datetime NOT NULL,
`CategoryId` int NOT NULL,
`StyleId` int NOT NULL,
`Image` varbinary(4000) NULL,
`TastingNotes` text NULL,
`Description` text NULL,
PRIMARY KEY (`ProductId`),
CONSTRAINT `FK_Product_Producers_ProducerId` FOREIGN KEY (`ProducerId`) REFERENCES `Producers` (`ProducerId`) ON DELETE CASCADE,
CONSTRAINT `FK_Product_ProductCategory_ProductCategoryId` FOREIGN KEY (`ProductCategoryId`) REFERENCES `ProductCategory` (`ProductCategoryId`) ON DELETE CASCADE,
CONSTRAINT `FK_Product_ProductStyle_ProductStyleId` FOREIGN KEY (`ProductStyleId`) REFERENCES `ProductStyle` (`ProductStyleId`) ON DELETE CASCADE
);
MySql.Data.MySqlClient.MySqlException (0x80004005): Cannot add foreign key constraint
at MySql.Data.MySqlClient.MySqlStream.ReadPacket()
at MySql.Data.MySqlClient.NativeDriver.GetResult(Int32& affectedRow, Int64& insertedId)
at MySql.Data.MySqlClient.Driver.GetResult(Int32 statementId, Int32& affectedRows, Int64& insertedId)
at MySql.Data.MySqlClient.Driver.NextResult(Int32 statementId, Boolean force)
at MySql.Data.MySqlClient.MySqlDataReader.NextResult()
at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader()
at MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery()
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteNonQuery(RelationalCommandParameterObject parameterObject)
at Microsoft.EntityFrameworkCore.Migrations.MigrationCommand.ExecuteNonQuery(IRelationalConnection connection, IReadOnlyDictionary`2 parameterValues)
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationCommandExecutor.ExecuteNonQuery(IEnumerable`1 migrationCommands, IRelationalConnection connection)
at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration)
at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.UpdateDatabase(String targetMigration, String contextType)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabaseImpl(String targetMigration, String contextType)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabase.<>c__DisplayClass0_0.<.ctor>b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
C
假设您的制作人与产品之间存在一对多关系,我会这样安排:
public class Producer
{
[Key]
public int ProducerID { get; set; }
[Required]
[StringLength(254)]
public string Name { get; set; }
public ICollection<Product> Products { get; set; }
}
public class Product
{
[Key]
public int ProductID { get; set; }
public int ProducerID { get; set; }
[Required]
[StringLength(254)]
public string Name { get; set; }
public Producer Producer { get; set;}
}
EF 将在从那里迁移期间完成繁重的工作,您可以检查上下文模型快照以确保它在更新数据库之前看起来正确。如果您还没有查看 Microsoft 文档中的 EF 教程,我建议您查看。
要添加 foreign key
只需将其添加到 Product
class 添加:
public int ProducerId { get; set; }
[ForeignKey("ProducerId")] //This attribute is optional bc EF should recognize Product obj specifi
public virtual Producer Producer { get; set; }
通过添加 public virtual Producer Producer
EF Core 应该将 ProducerId
属性 识别为 foreign key
。 virtual
用于启用 Lazy Loading
如果你喜欢。
[ForeignKey()]
是一个可选属性,用于显式指向 foreign
和 navigation
键。这个 post 应该进一步解释 [ForeignKey()]
的可选用法。
How Should I Declare Foreign Key Relationships Using Code First Entity Framework (4.1) in MVC3?
明确地说,要简单地添加一个 foreign
密钥,所需要的只是将其添加到 class:
public int ProducerId { get; set; }
public virtual Producer Producer { get; set; }
我正在使用 entity framework 的代码优先方法开发数据库。
我想在几个表之间使用外键,例如:
public class Producer
{
[Key]
public int Id { get; set; }
[Required]
[StringLength(254)]
public string Name { get; set; }
}
然后另一个文件模型被简化为
public class Product
{
[Key]
public int Id { get; set; }
[Required]
[StringLength(254)]
public string Name { get; set; }
}
我想要的是在产品上定义一个 ProducerId 字段并将其 link 到 Producers ID 字段,但我不知道如何告诉它 model/table 它的 link 到。
谁能澄清一下?我认为根据我阅读的内容,我似乎需要使 ID 字段更具描述性,EF 会找到该字段,ProductId 用于 Products Id 字段 - 但我仍然不肯定它会跨表工作。
这是正确的还是我错过了什么?
编辑:
我尝试了下面的第一个答案,但使用了比这两个更多的表,并得到了这个错误:
fail: Microsoft.EntityFrameworkCore.Database.Command[20102]
Failed executing DbCommand (46ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE `Product` (
`ProductId` int NOT NULL AUTO_INCREMENT,
`ProducerId` int NOT NULL,
`ProductCategoryId` int NOT NULL,
`ProductStyleId` int NOT NULL,
`Name` varchar(254) NULL,
`Year` datetime NOT NULL,
`CreatedAt` datetime NOT NULL,
`CategoryId` int NOT NULL,
`StyleId` int NOT NULL,
`Image` varbinary(4000) NULL,
`TastingNotes` text NULL,
`Description` text NULL,
PRIMARY KEY (`ProductId`),
CONSTRAINT `FK_Product_Producers_ProducerId` FOREIGN KEY (`ProducerId`) REFERENCES `Producers` (`ProducerId`) ON DELETE CASCADE,
CONSTRAINT `FK_Product_ProductCategory_ProductCategoryId` FOREIGN KEY (`ProductCategoryId`) REFERENCES `ProductCategory` (`ProductCategoryId`) ON DELETE CASCADE,
CONSTRAINT `FK_Product_ProductStyle_ProductStyleId` FOREIGN KEY (`ProductStyleId`) REFERENCES `ProductStyle` (`ProductStyleId`) ON DELETE CASCADE
);
Failed executing DbCommand (46ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE `Product` (
`ProductId` int NOT NULL AUTO_INCREMENT,
`ProducerId` int NOT NULL,
`ProductCategoryId` int NOT NULL,
`ProductStyleId` int NOT NULL,
`Name` varchar(254) NULL,
`Year` datetime NOT NULL,
`CreatedAt` datetime NOT NULL,
`CategoryId` int NOT NULL,
`StyleId` int NOT NULL,
`Image` varbinary(4000) NULL,
`TastingNotes` text NULL,
`Description` text NULL,
PRIMARY KEY (`ProductId`),
CONSTRAINT `FK_Product_Producers_ProducerId` FOREIGN KEY (`ProducerId`) REFERENCES `Producers` (`ProducerId`) ON DELETE CASCADE,
CONSTRAINT `FK_Product_ProductCategory_ProductCategoryId` FOREIGN KEY (`ProductCategoryId`) REFERENCES `ProductCategory` (`ProductCategoryId`) ON DELETE CASCADE,
CONSTRAINT `FK_Product_ProductStyle_ProductStyleId` FOREIGN KEY (`ProductStyleId`) REFERENCES `ProductStyle` (`ProductStyleId`) ON DELETE CASCADE
);
MySql.Data.MySqlClient.MySqlException (0x80004005): Cannot add foreign key constraint
at MySql.Data.MySqlClient.MySqlStream.ReadPacket()
at MySql.Data.MySqlClient.NativeDriver.GetResult(Int32& affectedRow, Int64& insertedId)
at MySql.Data.MySqlClient.Driver.GetResult(Int32 statementId, Int32& affectedRows, Int64& insertedId)
at MySql.Data.MySqlClient.Driver.NextResult(Int32 statementId, Boolean force)
at MySql.Data.MySqlClient.MySqlDataReader.NextResult()
at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader()
at MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery()
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteNonQuery(RelationalCommandParameterObject parameterObject)
at Microsoft.EntityFrameworkCore.Migrations.MigrationCommand.ExecuteNonQuery(IRelationalConnection connection, IReadOnlyDictionary`2 parameterValues)
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationCommandExecutor.ExecuteNonQuery(IEnumerable`1 migrationCommands, IRelationalConnection connection)
at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration)
at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.UpdateDatabase(String targetMigration, String contextType)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabaseImpl(String targetMigration, String contextType)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabase.<>c__DisplayClass0_0.<.ctor>b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
C
假设您的制作人与产品之间存在一对多关系,我会这样安排:
public class Producer
{
[Key]
public int ProducerID { get; set; }
[Required]
[StringLength(254)]
public string Name { get; set; }
public ICollection<Product> Products { get; set; }
}
public class Product
{
[Key]
public int ProductID { get; set; }
public int ProducerID { get; set; }
[Required]
[StringLength(254)]
public string Name { get; set; }
public Producer Producer { get; set;}
}
EF 将在从那里迁移期间完成繁重的工作,您可以检查上下文模型快照以确保它在更新数据库之前看起来正确。如果您还没有查看 Microsoft 文档中的 EF 教程,我建议您查看。
要添加 foreign key
只需将其添加到 Product
class 添加:
public int ProducerId { get; set; }
[ForeignKey("ProducerId")] //This attribute is optional bc EF should recognize Product obj specifi
public virtual Producer Producer { get; set; }
通过添加 public virtual Producer Producer
EF Core 应该将 ProducerId
属性 识别为 foreign key
。 virtual
用于启用 Lazy Loading
如果你喜欢。
[ForeignKey()]
是一个可选属性,用于显式指向 foreign
和 navigation
键。这个 post 应该进一步解释 [ForeignKey()]
的可选用法。
How Should I Declare Foreign Key Relationships Using Code First Entity Framework (4.1) in MVC3?
明确地说,要简单地添加一个 foreign
密钥,所需要的只是将其添加到 class:
public int ProducerId { get; set; }
public virtual Producer Producer { get; set; }