• Entity Framework 一对多关系映射


    EF中关系映射也是一个很关键的内容,关系映射和属性映射一样,也是在 OnModelCreating 中配置映射。EF中的关系映射有如下三种:

    1. One-to-Many Relationship(一对多)
    2. Many-to-Many Relationship(多对多)
    3. One-to-One Relationship(一对一)

    我们今天先讲解 One-to-Many Relationship(一对一关系)

    零、创建所需类

    • 所有实体类公用的抽象基类
    public abstract class Base
    {
        public int Id { get; set; }
        public DateTime CreateTime { get; set; }
        public DateTime ModifiedTime { get; set; }
    }
    
    • 客户类和订单类
    public class Customer : Base
    {
        public string Name { get; set; }
        public string Email { get; set; }
        public virtual ICollection<Order> Orders { get; set; }
    }
    
    public class Order : Base
    {
        public byte Quanatity { get; set; }
        public int Price { get; set; }
        public int CoustomerId { get; set; }
        public virtual Customer Customer { get; set; }
    }
    

    一、One-to-Many Relationship

    • 创建Map映射类

    在编写代码之前,我们先分析一下客户和订单的关系。一个客户可以有多个订单,但一个订单只能属于一个客户,所以我们用到了EF中的 HasRequired,一个客户又存在多个订单,因此也使用到了 WithMany ,同时 Order 表中有 CustomerId 作为外键,因此我们用到了 HasForeignKey 。根据我们的分析,编写代码如下:

    public class CustomerMap : EntityTypeConfiguration<Customer>
    {
        public CustomerMap()
        {
            //数据库映射的表名称
            ToTable("Customer");
            //主键
            HasKey(p => p.Id);
            //属性映射的字段属性
            Property(p => p.Name).HasColumnType("VARCHAR").HasMaxLength(50).IsRequired();
            Property(p => p.Email).HasColumnType("VARCHAR").HasMaxLength(50).IsRequired();
            Property(p => p.CreateTime);
            Property(p => p.ModifiedTime);
            //设置关系
            HasMany(t => t.Orders).WithRequired(t => t.Customer).HasForeignKey(t => t.CoustomerId).WillCascadeOnDelete(false);
        }
    }
    
    public class OrderMap : EntityTypeConfiguration<Order>
    {
        public OrderMap()
        {
            ToTable("Order");
            HasKey(p => p.Id);
            Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
            Property(p => p.Quanatity);
            Property(p => p.Price);
            Property(p => p.CoustomerId);
            Property(p => p.CreateTime);
            Property(p => p.ModifiedTime);
    
    
        }
    }
    
    • 注册映射类
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        var typeToRegister = Assembly.GetExecutingAssembly().GetTypes()
            .Where(t => !String.IsNullOrEmpty(t.Namespace))
            .Where(t => t.BaseType != null
            && t.BaseType.IsGenericType
            && t.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
    
        foreach(var type in typeToRegister)
        {
            dynamic configurationInstance = Activator.CreateInstance(type);
            modelBuilder.Configurations.Add(configurationInstance);
        }
        base.OnModelCreating(modelBuilder);
    }
    

    注1:在实际项目中需要编写很多的实体类,如果将所有实体类的映射直接写在 OnModelCreating 中会造成代码臃肿,不易维护,因此我们在这里将每个类的映射写在对应的映射文件中,最后再将每个类的映射类注册到 OnModelCreating

    注2:上述代码和描述是从客户的方向连编写的关系映射,如果以订单的角度来编写关系映射的话,只需删掉CustomerMap中的关系配置,在OrderMap中增加关系配置部分修改如下:

    HasRequired(p => p.Customer).WithMany(p => p.Orders).HasForeignKey(p => p.CoustomerId).WillCascadeOnDelete(false);
    

    运行控制台代码后,我们将在数据库看到表和表关系都被创建了:

    Z1xRKA.png

  • 相关阅读:
    paip.提高开发效率自动数据库SQL备份
    paip.提升开发效率增量备份项目文件
    paip.提升开发效率使用拼音
    paip.asp vbs代码的排版格式化
    paip.asp vbs的代码折叠代码结构查看
    paip.提升用户体验文件查找
    poj3026
    poj3020
    poj1182
    POJ典型算法例题题号
  • 原文地址:https://www.cnblogs.com/gangzhucoll/p/12778201.html
Copyright © 2020-2023  润新知