【问题标题】:Defining data annotation using DbContext versus Objectcontext in the database first approach在数据库优先方法中使用 DbContext 与 Objectcontext 定义数据注释
【发布时间】:2012-01-30 21:37:18
【问题描述】:

我在实体框架中使用数据库优先方法,当我使用默认模板工作时,数据库表是使用 ObjectContext 映射的,所以我曾经创建#partial 类和 [MetadataType(typeof) 来应用数据注释,但是当我开始使用 Dbcontext 代码生成模板来映射数据库表时,我发现它将在我的模型区域中创建 .tt 文件夹,我发现 我可以将数据注释直接应用于 .cs 类无需像在 objectcontext 情况下那样创建部分类。 目前,数据注释工作正常,但是我的方法会导致我不知道的问题,我应该像以前对 Objectcontext 所做的那样创建部分类? BR

【问题讨论】:

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


    【解决方案1】:

    一般来说,您不应编辑生成的代码,因为您所做的更改将在重新生成时被覆盖。这就是大多数生成器发出部分类的原因。

    适合您情况的最佳做法是在您的解决方案中使用另一个部分类声明创建一个新文件。在该文件中,将MetadataType 属性添加到类,并将您的属性级验证属性添加到“伙伴”类(属性中引用的那个)。这允许您在生成的属性上使用验证属性,并且如果您的模型/数据库发生更改,您仍然可以重新生成模型类而不会丢失它们。

    例如,您的新文件可能类似于:

    [MetadataType(typeof(PersonMetadata))]
    partial class Person
    {
        // Add logic to the generated class in here.
    
        public string FullName
        {
            get { return FirstName + " " + LastName; }
        }
    }
    
    class PersonMetadata
    {
        // Add attributes to the generated properties in here.
    
        [Required]
        public string FirstName { get; set; }
    }
    

    【讨论】:

    • 如果我使用 ObjectContext,您的点将是有效的,因为该模板将创建模型类而不是像 DbContext 模板案例中的部分类。因此,在 DBContext 模板中,如果我想添加任何辅助方法,我应该在自动生成的部分类中执行它,因为我无法在元数据类型类中添加辅助方法,所以通过这种方式辅助方法被添加到自动生成的代码中,这意味着如果我重新生成代码,我会丢失它。任何建议。BR
    • MetadataType 仅用于向已声明的属性添加属性(因为不能使用部分属性)。所有其他辅助逻辑都可以通过部分类的非生成文件部分直接添加到类中。
    • 我认为 .tt 文件夹下的整个部分类将被删除并重新创建,以防我重新生成代码,我不知道你所说的“非生成文件的部分”是什么意思部分课程。”,你能解释一下吗? BR
    • @johnG 正确,您不应该修改 .tt 项下的文件。我建议您在解决方案中创建一个新文件,其中包含另一个 partial class delcaration。 (部分类的目的是将类拆分为多个文件。)
    • @johnG,我已经更新了答案,希望能让事情变得更清楚。
    【解决方案2】:

    创建相同的部分类来定义您的元数据,或者您可以使用 Entity Framework Power Tools 简单地对现有数据库进行逆向工程,这样您就有了 POCO 类。然后,您可以使用 fluent API(您将看到它为您添加的验证)而不是数据注释来为您提供服务器端验证。

    如果您想要客户端,那么您仍然可以将它们应用于您的模型,因为它们不会在您每次编译时重新生成。

    但是 - 我建议您创建 ViewModel 并使用 AutoMapper 在您的 EF 对象和视图模型之间进行映射。然后,您可以将注释直接应用到您的 ViewModel。

    【讨论】:

    • 实际上我注意到 .tt 文件夹下的类默认是部分类,所以这意味着如果我想修改数据库并再次重新创建 Dbcontext 所有数据注释和助手方法将被删除,那么我怎样才能避免这种情况,所以即使再次重新创建 Dbcontext,所有数据注释和辅助方法也不会被删除?
    • 如果您使用 tt 模板,那么您需要使用部分类,除非您修改 tt 模板以根据模型架构为您添加它们......或者您像我提到的那样进行逆向工程跨度>
    • 但是我不能创建相同的部分类来定义我的元数据,因为 Visual Studio 会引发一个错误,即类已经存在。
    • 你可以有5个同名的部分类,这就是它们的重点。您创建另一个具有您的 MetaDataType 属性的部分类。然后创建第三个类,其中包含数据注释。见:msdn.microsoft.com/en-us/library/ie/ee256141.aspx
    【解决方案3】:

    我对您的情况的理解是,您将 Database-First 样式反向工程为 Code-First 样式。如果您的上下文类继承自 DbContext,那么您现在处于 Code-First 风格(除非有一些奇怪的混合可能,我不知道!)。

    在代码优先中,为数据注释创建部分类确实没有意义,IMO。

    【讨论】:

    • 我使用 Dbcontext 代码生成来映射我现有的表,然后它创建 .tt 文件夹,其中包含我的表作为类;所以我可以将客户端数据注释应用到类本身。所以我开始使用 Db first apprach 和他们在映射之后我在 Code first apprach 中。 BR
    • 但是如果我将数据注释直接应用到类中,那么我将丢失它们,以防我需要修改数据库并重新生成实体框架类。 BR
    • DbContext 并非代码优先工作流所独有。您可以将 EntityConnection 传递给构造函数,以从实体数据模型加载元数据,而不是从代码构建它。 DbContext template 启用此功能。
    • 但是如果我将数据注释应用于自动生成的部分类,那么如果我重新生成代码,我将丢失这些定义。
    • @johnG 正确,我提出的答案解决了这个问题。 Mathieu 假设您使用的是代码优先的工作流程,但事实并非如此。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-04
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    相关资源
    最近更新 更多