繁体   English   中英

实体框架 - 代码优先 - 外键约束

[英]Entity Framework - Code First - Foreign Key Constraint

我正在使用实体框架的代码优先方法开发数据库。

我想在几个表之间使用外键,例如:

 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 字段并将其链接到 Producers ID 字段,但我无法告诉它如何告诉它链接到哪个模型/表。

任何人都可以澄清吗? 我认为根据我阅读的内容,我似乎需要使 ID 字段更具描述性,EF 会找到该字段,即 Products Id 字段的 ProductId - 但我仍然不确定它是否可以跨表格工作。

这是正确的还是我错过了什么?

编辑:

我尝试了下面的第一个答案,但使用的表不仅仅是这两个,并得到了这个错误:


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 Docs 中的 EF 教程。

要添加foreign key只需在Product类中添加以下内容:

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键。 这篇文章应该进一步解释[ForeignKey()]的可选使用。 我应该如何在 MVC3 中使用代码优先实体框架 (4.1) 声明外键关系?

需要明确的是,只需添加一个foreign键,所需要做的就是将其添加到类中:

public int ProducerId { get; set; }
public virtual Producer Producer { get; set; }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM