• Entity Framework Code First约定


    Code First使你能够通过C# 或者 Visual Basic .NET来描述模型,模型的基本规则通过使用约定来进行检查,而约定就是一系列内置的规则。

    Code First中基于类的定义通过一系列的规则约定自动配置概念模型,约定被定义在命名空间System.Data.Entity.ModelConfiguration.Conventions中。

    你可以进一步配置你的模型通过数据注解或者fluent API。

    优先通过 fluent API配置紧随其后的是数据注解约定。更多信息可以查看Data Annotations, Fluent API - Relationships, Fluent API - Types & Properties and Fluent API with VB.NET.

    关于Code First的一系列约定可以参考API Documentation.这篇文章的主题主要阐述了Code First的约定

    类型探索

    当我们使用Code First开发的时候,通过写.NET Framework类来定义概念(领域)模型,除了定义类之外,你还需要让DbContext知道哪些类型是你想要代表的模型。因此,你需要定义一个上下文类继承自DbContext,用DbSet修饰你需要表示为模型的类型。Code First将包含这些类型并获取这个引用类型,即使引用来下被定义在不同的程序集当中。

    如果你的类在继承结构体系当中,这些类在同一个程序集下面时,你将基类定义成一个DbSet属性就足够了,它将自动推断出所包含的其它相关联的类型。

    public class SchoolEntities : DbContext 
    { 
        public DbSet<Department> Departments { get; set; } 
    } 
     public class Department 
    { 
        // Primary key 
        public int DepartmentID { get; set; } 
        public string Name { get; set; } 
     
        // Navigation property 
        public virtual ICollection<Course> Courses { get; set; } 
    } 
     public class Course 
    { 
        // Primary key 
        public int CourseID { get; set; } 
     
        public string Title { get; set; } 
        public int Credits { get; set; } 
     
        // Foreign key 
        public int DepartmentID { get; set; } 
     
        // Navigation properties 
        public virtual Department Department { get; set; } 
    } 
         public partial class OnlineCourse : Course 
    { 
        public string URL { get; set; } 
    } 
     public partial class OnsiteCourse : Course 
    { 
        public string Location { get; set; } 
        public string Days { get; set; } 
        public System.DateTime Time { get; set; } 
    }

    如果你不想让某一个类型作为模型类,你可以使用 NotMapped 属性或者使用 fluent API的DbModelBuilder.Ignore.

    modelBuilder.Ignore<Department>();

    主键约定

    如果在类中存在名为"ID"(不区分大小写)的属性或者是类名+"ID",Code First将自动推断这个属性作为主键。

    public class Department 
    { 
        // Primary key 
        public int DepartmentID { get; set; }  
        . . .   
    }

    关系约定

    Entity Framework中,导航属性提供两个实体类型之间的跳转,导航属性允许你从两个方向导航和管理关系,它返回一个引用对象(1个或者0个)或者一个集合(多个对象列表)。Code First 是基于导航属性来推断类型直接的关系的。

    除了导航属性之外,建议你添加一个外键属性去表示对象直接的依赖关系。

    遵循以下格式将表示一个外键的关系:<导航属性名称><被导航实体的主键名称>,<被导航实体的类名称><被导航实体的主键名称>,或者<被导航实体的主键名称>,如果找到了多个这样的匹配关系,将按照上面所给出的先后顺序来推断。外键检测是不区分大小写的。

    当检测到一个外键属性, Code First基于可空的外键推断出关系。如果属性是可空的表示这个关系是可选的,否则这个关系将是必须注册的。

    如果外键依赖的实体是不可空的, Code First 将设置级联删除的关系。如果外键依赖的实体是可空的,Code First将不设置级联删除关系,当引用的实体删除时,外键将被设置为null。更加多样的级联删除我们可以通过使用fluent API.来重新设置约定。

    在如下的例子中导航属性和外键将被用于定义Department 和Course 类之间的关系。

    public class Department 
    { 
        // Primary key 
        public int DepartmentID { get; set; } 
        public string Name { get; set; } 
     
        // Navigation property 
        public virtual ICollection<Course> Courses { get; set; } 
    } 
     public class Course 
    { 
        // Primary key 
        public int CourseID { get; set; } 
     
        public string Title { get; set; } 
        public int Credits { get; set; } 
     
        // Foreign key 
        public int DepartmentID { get; set; } 
     
        // Navigation properties 
        public virtual Department Department { get; set; } 
    }

    注意:如果存在多个相同类型之间的关系(比如,假设你定义了Person and Book类,Person 类包含了 ReviewedBooks and AuthoredBooks这两个导航属性,同时Book类又包含了 Author and Reviewer导航属性 )你需要手动的通过Data Annotations 或者 the fluent API来配置关系。更多信息,请参考 Data Annotations - RelationshipsFluent API - Relationships.

    复制类型约定

    Code First发现一个类的主键无法推测, 并且没有通过data annotations 或者fluent API来标识,那么这个类型将自动被当成一个复杂类型来处理,复杂类型要求它不存在引用其他实体类型的属性。

    下面的类Details 将被当成复杂类型,因为它没有设置主键

    public partial class OnsiteCourse : Course 
    { 
        public OnsiteCourse() 
        { 
            Details = new Details(); 
        } 
     
        public Details Details { get; set; } 
    } 
     
    public class Details 
    { 
        public System.DateTime Time { get; set; } 
        public string Location { get; set; } 
        public string Days { get; set; } 
    }

    连接字符串约定

    学习更多关于 DbContext连接的约定可以查看 Connections and Models.

    移除约定

    在命名空间System.Data.Entity.ModelConfiguration.Conventions中,你可以移除约定,以下例子将移除PluralizingTableNameConvention.

    public class SchoolEntities : DbContext 
    { 
         . . . 
     
        protected override void OnModelCreating(DbModelBuilder modelBuilder) 
        { 
            // Configure Code First to ignore PluralizingTableName convention 
            // If you keep this convention, the generated tables  
            // will have pluralized names. 
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); 
        } 
    }

    自定义约定

    自定义约定在EF6开始支持,更多信息请查看 Custom Code First Conventions.

    老外的文章真的是写得非常精彩,所以我强烈建议大家去看英文技术博客和文章,看不懂就硬着头皮看,久了自然就看得懂了,一开始即使看不懂文字说明,看看代码也好呀。

    由于本人英文实在太烂,所以如果有翻译得不通顺的地方还忘见谅,大家可以参考原文,原文地址:Entity Framework Code First Conventions

  • 相关阅读:
    C# Note23: 如何自定义类型使用foreach循环
    C# Note22: 《Effective C#》笔记
    C# Note21: 扩展方法(Extension Method)及其应用
    C# Note20: 制作延时改变显示的标题栏
    C# Note19: Windows安装包制作实践
    Python Note1: Pycharm的安装与使用
    java Html&JavaScript面试题:HTML 的 form 提交之前如何验证数值文本框的内容全部为数字? 否则的话提示用户并终止提交?
    java Html&JavaScript面试题:用table显示n条记录,每3行换一次颜色,即1,2,3用红色字体,4,5,6用绿色字体,7,8,9用红颜色字体。
    java Html&JavaScript面试题:判断第二个日期比第一个日期大
    java算法面试题:金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)->(一千零一拾一元整)输出。
  • 原文地址:https://www.cnblogs.com/jiekzou/p/6422978.html
Copyright © 2020-2023  润新知