实体框架手册数据库更改

时间:2017-07-10 15:40:48

标签: .net entity-framework

我正在关注Udemy构建.net和mvc5项目的课程。该项目涉及使用代码的第一个数据库设计理念。在练习之后,我得到了一些混乱的东西,所以我去了导师github代码库并下载了一些类。在其中一个类中,他在Movie类中有一个名为Genre_Id的列名,而我将我的版本命名为GenreId。所以我愚蠢地进入电影类并调用Genre_Id列并转到数据库并手动将列重命名为Genre_Id。这个手动更改立即开始在我的应用程序中抛出异常。

当我尝试构建我的应用程序时,我会抛出系统异常。我做了一些研究,发现一篇帖子建议重新初始化迁移可以解决异常问题。所以我删除了我的迁移文件夹,断开了数据库连接并删除了数据库,以便我可以从头开始重新创建迁移和数据库模式。我似乎没有得到的是为什么Visual Studio仍然使用Genre_Id1创建迁移,当我的电影类不包含该列名时,Genre_Id1是一个外键。

在我从头开始重建整个解决方案之前,任何人都可以帮助我。我有的例外是内部异常:列名“Genre_Id1”无效。我在整个解决方案中搜索了Genre_Id1,检查了我的类,确保在更新数据库之前删除了包含Genre_Id1的add-migration InitialMigration并替换为Genre_Id,但我不确定它在哪里定义或获取此列名称,因为构建过程似乎在寻找它。

在我废弃项目并重新启动之前,我可以尝试其他任何内容。

由于

1 个答案:

答案 0 :(得分:2)

您遇到的问题源自EF(不是您)之前的EF Core选择不当的默认约定。

如果您的类具有导航属性且没有explcit FK属性:

public class Movie
{
    // ...
    public Genre Genre { get; set; }
}

隐含的影子FK属性和列名称为Genre_Id

但显式FK属性名称的默认约定是GenreId(无下划线)。提供时也会更改隐含的列名称:

public class Movie
{
    // ...
    public int GenreId { get; set; }
    public Genre Genre { get; set; }
}

当您将属性命名为Genre_Id

public class Movie
{
    // ...
    public int Genre_Id { get; set; }
    public Genre Genre { get; set; }
}
按惯例,

EF不会将其识别为FK属性,并会尝试使用默认名称Genre_Id创建隐藏(阴影)属性。由于名称由您的属性保留,因此EF会附加后缀以使其唯一,因此您在生成的SQL中会看到Genre_Id1

有几种方法可以解决它。我个人更喜欢流畅的配置,因为它更干净的IMO,但这里是你如何使用数据注释来解决它:

如果您想要名为Genre_Id的FK属性,请使用[ForeignKey]属性将其映射为FK:

public class Movie
{
    // ...
    [ForeignKey("Genre")]
    public int Genre_Id { get; set; }
    public Genre Genre { get; set; }
}

public class Movie
{
    // ...
    public int Genre_Id { get; set; }
    [ForeignKey("Genre_Id")]
    public Genre Genre { get; set; }
}

如果您需要名为GenreId的属性,请使用[Column]属性指定列名称:

public class Movie
{
    // ...
    [Column("Genre_Id")]
    public int GenreId { get; set; }
    public Genre Genre { get; set; }
}

我建议您始终创建一个显式迁移并查看它包含的内容。如果您看到未指定的列,则表明某些不正确的配置会导致与EF默认约定冲突。