zoukankan      html  css  js  c++  java
  • Entity Framework 一对一关系映射

    一对一关系是Entity Framework 中很复杂的关系,涉及了 HasOptionalWithRequiredWithOptionalPrincipalWithOptionalDependent。这篇文章我们将具体讲解这几个的用法。

    我们以会员和订单为例,一个会员有可能有订单,也可能没有订单,但是一个订单绝对属于一个会员。我们先编写出会员和订单的类代码:

    public class Member
    {
        public int Id { get; set; }
    
        public string Name { get; set; }
        public virtual Order Order { get; set; }
    }
    public class Order
    {
        public int Id { get; set; }
        public int Name { get; set; }
        public int Num { get; set; }
    
        public virtual Member Member { get; set; }
    }
    
    

    零、 HasOptionl then WithRequired

    这种方式的会员和订单的映射类如下:

    public class MemberMap : EntityTypeConfiguration<Member>
    {
    
        public MemberMap()
        {
            ToTable("Member");
            HasKey(p => p.Id);
            Property(p => p.Id)
                .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
            HasOptional(p => p.Order).WithRequired(p => p.Member);
    
        }
    }
    
    public class OrderMap : EntityTypeConfiguration<Order>
    {
        public OrderMap()
        {
            ToTable("Order");
            HasKey(p => p.Id);
            Property(p => p.Id).HasColumnName("MemberId")
                .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
        }
    }
    

    这里将 Member 类的Id设为自增长,将 Order 的Id设置别名 MemberId 且非自增长。编写晚上下文类和调用类后,运行代码后,我们在数据库中将看到如下图:

    Zz7Ade.png

    其中 MemberId 就是在 OrderMap 中设置的别名

    一、 HasOptionl then WithOptionalPrincipal

    现在我们修改一下 MemberMapOrderMap ,将 MemberOrder 的Id都设置成自增长。

    public class MemberMap : EntityTypeConfiguration<Member>
    {
    
        public MemberMap()
        {
            ToTable("Member");
            HasKey(p => p.Id);
            Property(p => p.Id)
                .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
            HasOptional(p => p.Order).WithOptionalPrincipal(p => p.Member);
    
        }
    }
    
    public class OrderMap : EntityTypeConfiguration<Order>
    {
        public OrderMap()
        {
            ToTable("Order");
            HasKey(p => p.Id);
            Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        }
    }
    

    再次执行代码后,查看生成的数据库:

    ZzbZvt.png

    我们看到 Order 表中 Member_Id 字段是EF自动生成的外键,且不可为空

    二、 HasOptionl then WithOptionalDependent

    再次修改 MemberMapOrderMap

    public class MemberMap : EntityTypeConfiguration<Member>
    {
    
        public MemberMap()
        {
            ToTable("Member");
            HasKey(p => p.Id);
            Property(p => p.Id)
                .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
            HasOptional(p => p.Order).WithOptionalDependent(p => p.Member);
        }
    }
    
    public class OrderMap : EntityTypeConfiguration<Order>
    {
        public OrderMap()
        {
            ToTable("Order");
            HasKey(p => p.Id);
            Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        }
    }
    

    保存代码,运行程序,查看数据库:

    ZzqDw8.png

    和上一小节生成的数据库相比,这一小节生成的数据库 Member 表中自动生成了 Order 表的外键 Order_Id ,而 Order 表没有生成任何外键。

    注:使用 WithOptionalPrincipal 可以使实体作为主体,将包含关系主键。使用 WithOptionalDependent 可以使实体作为以来提,将包含关系的外键。

    前面所讲的都是从 Member 入手,我们同样也可以从 Order 表入手,但是在实际开发中我不建议这么做。下面就来说一下从 Order 入手的方法。

    三、 HasRequired then WithOptional

    同样我们修改 MemberMapOrderMap

    public class MemberMap : EntityTypeConfiguration<Member>
    {
    
        public MemberMap()
        {
            ToTable("Member");
            HasKey(p => p.Id);
            Property(p => p.Id)
                .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        }
    }
    
    public OrderMap()
    {
        ToTable("Order");
        HasKey(p => p.Id);
        Property(p => p.Id).HasColumnName("MemberId").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
    
        HasRequired(p => p.Member).WithOptional(p => p.Order);
    
    }
    

    这种方法生成的数据库与第一种方法结果一样。

    四、 HasRequired 和 WithOptional

    我们最后一次修改 MemberMapOrderMap

    public class MemberMap : EntityTypeConfiguration<Member>
    {
    
        public MemberMap()
        {
            ToTable("Member");
            HasKey(p => p.Id);
            Property(p => p.Id)
                .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        }
    }
    
    public class OrderMap : EntityTypeConfiguration<Order>
    {
        public OrderMap()
        {
            ToTable("Order");
            HasKey(p => p.Id);
            Property(p => p.Id).HasColumnName("MemberId").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
    
            HasRequired(p => p.Member).WithOptional(p => p.Order).Map(p => p.MapKey("Member_Id")))
    
        }
    }
    
    

    这种方法生成的数据库与第二种方法结果一样。

  • 相关阅读:
    如何给工科生做一个演讲DEMO
    JAVA事务处理系列 值得看
    今天开通了博客,准备开始写点东西或者记录点东西!或者转载点东西!
    屌丝程序员如何打造日PV百万的网站架构
    拥抱大数据时代 DB架构设计
    根据并发请求id查找相应trace信息
    FRM30187: Size of CHAR column in record group must be between 1 and 2000
    10046 SQL trace 的做法
    Oracle 表空间不足的处理办法
    LoadRunner在EBS R12上运行需更改服务器为Socket模式
  • 原文地址:https://www.cnblogs.com/gangzhucoll/p/12778185.html
Copyright © 2011-2022 走看看