【问题标题】:Database-first approach and modifying the database schema数据库优先方法和修改数据库模式
【发布时间】:2012-01-30 22:38:30
【问题描述】:

我正在使用实体框架 DbContext 使用数据库优先方法构建一个 ASP.NET MVC Web 应用程序。

如果在某些情况下我需要修改数据库,例如添加新表或修改现有表(添加列或更改列数据类型),我应该:

  1. 删除现有实体 .edmx 和 .tt 文件夹并重新创建映射
  2. 修改数据库后手动将修改应用到.tt文件夹下的模型类
  3. 这两个选项均无效。

我应该如何处理修改我的数据库架构的任务?

已编辑 例如,我在 .tt 文件夹下自动创建了以下部分类,记住我添加了 *IsManagedBy* 辅助方法和 [MetadataType(typeof (Books_validation))] 给它:-

[MetadataType(typeof(Books_validation))]
    public partial class Book
    {
        public Book()
        {
            this.Assessments = new HashSet<Assessment>();
            this.Users_Books = new HashSet<Users_Books>();
        }

        public int BookID { get; set; }


        public string BookName { get; set; }
        public string ManagedBy { get; set; }

        public byte[] Timestamp { get; set; }

        public virtual ICollection<Assessment> Assessments { get; set; }
        public virtual User User { get; set; }
        public virtual ICollection<Users_Books> Users_Bookes { get; set; }
        public bool IsManagedBy(string userName)
        {
            return ManagedBy.Equals(userName,
            StringComparison.OrdinalIgnoreCase);
        }

    }

然后我创建 Book_validation 类来应用数据注释,如下所示:-

public class Books_validation

    {

        [Required(ErrorMessage = "Name is required")]
        public string BookName { get; set; }
        public string ManagedBy { get; set; }
       [ConcurrencyCheck]
        [Timestamp]
       public Byte[] Timestamp { get; set; }

    }

这种方法会导致三个问题:-

1. IsManagedBy 辅助方法不能在 Book_validation 类中定义,我应该在自动生成的 Book 分部类中定义它,这意味着如果我重新生成代码,它将被删除! .

2. 例如,如果我修改了与 Book 类相关的评估表(通过外键),然后我从 .edmx 设计器中选择了“从数据库更新模型”选项;那么visual studio也会重新生成Book类,这会给我带来更多的麻烦。

3.即使是我在自动生成的代码中写的[MetadataType(typeof(Books_validation))]也会被删除,以防我重新生成代码,所以这意味着我必须去覆盖所有修改过的类,并为它们添加关联的 MetadataType(typeof)。

当我使用 ObjectContext 模板时,所有这些问题都没有发生,因为 ObjectContext 模板不会自动生成部分类,它只会生成模型类,然后我可以为它们添加部分类和元数据类型......所以我认为最好返回 ObjectContext 而不是 DBContext !!!,对这个和上述问题有什么建议吗? BR

【问题讨论】:

    标签: asp.net-mvc-3 entity-framework


    【解决方案1】:

    如果您在 EDMX 编辑器中单击鼠标右键,应该会出现“从数据库更新模型”选项。如果您已删除数据库中的字段,您可能仍需要删除它们,甚至删除它们的表并通过“从数据库更新模型”菜单重新添加它,但我发现这比删除整个 edmx 并开始更容易每次都很新鲜。

    更新

    正如 Ladislav 所说,您永远不应该乱用自动生成的代码文件。正如您所发现的,这些代码文件会自动重写。 Entity Framework 的创建者预见到您遇到的问题,他们提供了一种机制,您可以在不修改自动生成的 .cs 文件的情况下添加到这些类:部分类

    部分类允许您创建跨多个文件的类定义,前提是它们都位于相同的命名空间和程序集中。因此,除了自动生成的 Context.cs 文件之外,您还可以创建其他文件,如下所示:

    书籍.cs

    [MetadataType(typeof(Books_validation))]
    public partial class Book
    {
        public bool IsManagedBy(string userName)
        {
            return ManagedBy.Equals(userName,
            StringComparison.OrdinalIgnoreCase);
        }
    }
    

    分部类的这种单独定义的存在将导致此代码在编译程序集时与自动生成的 Book 类有效地“合并”,但它允许您将这个特殊的自定义代码放在单独的文件中从 EDMX 文件重新生成模型数据时不会受到影响。

    【讨论】:

    • 我尝试从数据库表中删除一个字段,然后我使用“从数据库更新模型”并选择了我修改过的表,但我注意到 Visual Studio 已经重新创建了模型表示修改后的表的类和通过 FK 关系连接到该表的所有类,以及我在 .tt 文件夹下的类中创建的所有数据注释和辅助方法都被删除了......所以我怎样才能避免这些两个问题(影响其他表并保留数据注释和辅助方法)。 BR
    • @johnG:我已经读过你的 cmets 几遍了,恐怕我不明白你在说什么。它如何影响其他表?你失去了哪些辅助方法?请使用一些代码更新您的问题,以显示您正在谈论的一些示例。
    • 感谢 StriplingWarrior,我已经编辑了我的帖子以使其更清晰。 BR
    • 感谢您的回复;但是 DBContext 模板会在 .tt 文件夹下自动生成部分类,所以如果我尝试添加一个新的部分类,如下所示:-“公共部分类书”。 Visual Studio 将引发该类已存在的错误... BR
    • 好的,它工作得很好,我将新文件命名为 Book2.cs,这样我就不会收到该类已经存在的错误,然后在 Book2.cs 中我定义了“公共部分类 Book 。 ... BR
    【解决方案2】:

    您不应该修改自动生成的代码。如果您这样做,您无论如何都会破坏整个工作流程,因为对 EDMX 文件的任何单个更改都可能会删除您的更改。所有自定义代码都属于您自己的部分类(例如用于adding validation 数据注释)。

    一旦您遵循正确的工作流程,您将能够修改 EDMX 并使用从数据库更新,这是将更改从数据库推送到您的代码的唯一正确方法。

    【讨论】:

    • 但在我使用的 DBContext 模板案例中,DbContext 将在 .tt 文件夹中自动生成部分类。所以我将无法为模型对象定义新的部分类,因为 Visual Studio 将引发该类已经存在的错误!!!。 BR
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-22
    • 1970-01-01
    • 1970-01-01
    • 2020-02-21
    • 1970-01-01
    • 1970-01-01
    • 2019-06-04
    相关资源
    最近更新 更多