Entity Framework学习二:定义数据结构

  1. 映射.NET类型和SQL类型QQ图片20150920074733

也可以在微软网站查找完整对应列表:http://msdn.microsoft.com/en-us/library/cc716729(v=vs.110).aspx

2.配置数据结构

可以使用以下几种方式来配置

• Attributes
• Configuration Classes
• The DbModelBuilder API

2.1使用Attributes方式:

public class Person
    {       
        public int PersonId { get; set; }
        [MaxLength(30)]
        public string FirstName { get; set; }
        [MaxLength(30)]
        public string LastName { get; set; }

        [StringLength(1, MinimumLength = 1)]
        [Column(TypeName = "char")]
        public string MiddleName { get; set; }
    }

image

创建出来的数据表结构如上,跟你在类中定义的Attribute是对应的。

2.2使用DbModelBuilder API

使用这种方法需要override DbContext下的OnModelCreating方法,使用此方法就不用再用上面的Attribute方法设置了.

public class Context:DbContext
    {
        public Context() : base("ConnectionString")//为配置文件中连接字符串名称
        {
        }

        public DbSet<Person> People { get; set; }
        public DbSet<Company> Companies { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Person>().Property(p => p.FirstName)
                .HasMaxLength(30);
            modelBuilder.Entity<Person>().Property(p => p.LastName)
                .HasMaxLength(30);
            modelBuilder.Entity<Person>().Property(p => p.MiddleName)
                .HasMaxLength(1)
                .IsFixedLength()
                .IsUnicode(false);
        }
    }

这里有个问题,如果只有一个表,那么在重写里面代码不到,如果很多表,就会很多很乱,这时候我们增加Person类的PersonMap类来解决

public class PersonMap : EntityTypeConfiguration<Person>
    {
        public PersonMap()
        {
            Property(p => p.FirstName)
                .HasMaxLength(30);
            Property(p => p.LastName)
                .HasMaxLength(30);
            Property(p => p.MiddleName)
                .HasMaxLength(1)
                .IsUnicode(false)
                .IsFixedLength();
        }
    }

这样定义以后我们只需要在DbContex的OnModelCreaing中注册就可以了。

protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Configurations.Add(new PersonMap());

        }

2.3定义关系

  • 1对多关系

          一个人可以有多个电话号码。我们创建Phone类

public class Phone
    {
        public int PhoneId { get; set; }
        public string PhoneNumber { get; set; }

        public int  PersonId { get; set; }
    }

在Phone中我们定义了PersonId作为外键。在Person类中定义ICollectionPhone> Phones,注意这里使用了virtual修饰,是为了延迟加载。在Person构造函数中初始化对象。

public class Person
    {
        public Person()
        { Phones = new HashSet<Phone>(); }
        public int PersonId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }

        public string MiddleName { get; set; }

        public virtual ICollection<Phone> Phones { get; set; }
    }

那么接下来我们在前面定义的PersonMap类中定义Person可以包含多个Phone。代码如下(注意标记部分为新增代码):

public class PersonMap : EntityTypeConfiguration<Person>
    {
        public PersonMap()
        {
            Property(p => p.FirstName)
                .HasMaxLength(30);
            Property(p => p.LastName)
                .HasMaxLength(30);
            Property(p => p.MiddleName)
                .HasMaxLength(1)
                .IsUnicode(false)
                .IsFixedLength();

this.HasMany(p => p.Phones) .WithRequired() .HasForeignKey(ph =>
ph.PersonId);
        }
    }

接下来我们要在Contex中定义Dbset<Phone>.代码如下:

public class Context:DbContext
    {
        static Context()
        {
            Database.SetInitializer<Context>(null);//当Model发生改变时不自动创建数据库
        }
        public Context() : base("ConnectionString")//为配置文件中连接字符串名称
        {            
        }

        public DbSet<Person> People { get; set; }
        public DbSet<Company> Companies { get; set; }

        public DbSet<Phone> Phones { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            
            modelBuilder.Configurations.Add(new PersonMap());
        }
    }

我们还要在数据库中创建表Phone已经Phone和Person的外键关联imageimage

以及要设置级联更新和级联删除,不然更新和删除是会报错。

  • 多对多关系

        考虑以下场景,一个公司可以有多位雇员,一个人也可以为多个公司工作。增加Company类

public class Company
    {
        public Company()
        {
            People = new HashSet<Person>();
        }
        public int CompanyId { get; set; }
        public string Name { get; set; }

        public ICollection<Person> People { get; set; }
    }

    public class CompanyMap : EntityTypeConfiguration<Company>
    {
        public CompanyMap()
        {
            ToTable("Company");
        }
    }

 

在Person类增加

public virtual ICollection<Company> CompanyList { get; set; }

PersonMap类增加

HasMany(p => p.CompanyList)
                .WithMany(c => c.People)
                .Map(m => 
                {
                    m.ToTable("PersonCompany");//设置关联表名称
                    m.MapLeftKey("PersonId");//
                    m.MapRightKey("CompanyId");
                });

 

在Contex类增加如下标记的代码:

public class Context:DbContext
    {
        static Context()
        {
            Database.SetInitializer<Context>(null);//当Model发生改变时不自动创建数据库
        }
        public Context() : base("ConnectionString")//为配置文件中连接字符串名称
        {            
        }

        public DbSet<Person> People { get; set; }
        public DbSet<Company> Companies { get; set; }

        public DbSet<Phone> Phones { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            
            modelBuilder.Configurations.Add(new PersonMap());
            modelBuilder.Configurations.Add(new CompanyMap());
        }
    }

接着我们要在数据库中增加表名为Company的数据表,结构如下:image以及PersonCompany表:image。注意这里有两个外键设置,分别对应People表中的PersonId和Company表中的CompanyId,并设置了级联删除关联。

下面是测试代码:

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("开始处理数据");
            using (var context=new Context())
           { 
                var person = new Person
                {
                     LastName = "Doe",
                        FirstName = "John"
                };
                 person.CompanyList.Add(new Company { Name = "厂一" });
                 person.CompanyList.Add(new Company { Name = "厂二" });
                 context.People.Add(person);
                 context.SaveChanges();
            }
            Console.WriteLine("处理完毕");
            Console.ReadKey();
       }
}

执行完以上代码可以发现在People表,Company表和PersonCompany表都增加了数据。删除People表或者Company表数据时会级联删除 PersonCompany表相关数据。

  • 一对一关系

     考虑如下场景,每个学生对应于一个人,增加Student类

public class Student
    {
        public int PersonId { get; set; }

        public Person Person { get; set; }
        public string CollegeName { get; set; }
        public DateTime EnrollmentDate { get; set; }

    }

    public class StudentMap : EntityTypeConfiguration<Student>
    {
        public StudentMap()
        {
            ToTable("Student");//表名为:Student

            HasRequired(s => s.Person)
                .WithRequiredDependent(p=> p.Student); //设置对应关系
            HasKey(s => s.PersonId);  //设置主键
            Property(s => s.CollegeName)
                .HasMaxLength(50).IsRequired();
        }
    }
在Person类和PersonMap中增加
public class Person
    {
        public Person()
        {
            Phones = new HashSet<Phone>();
            CompanyList = new HashSet<Company>();
        }
        public int PersonId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }

        public string MiddleName { get; set; }

        public virtual ICollection<Phone> Phones { get; set; }

        public virtual ICollection<Company> CompanyList { get; set; }

        public Student Student { get; set; }
    }

在Context类中增加:

public class Context:DbContext
    {
        static Context()
        {
            Database.SetInitializer<Context>(null);//当Model发生改变时不自动创建数据库
        }
        public Context() : base("ConnectionString")//为配置文件中连接字符串名称
        {            
        }

        public DbSet<Person> People { get; set; }
        public DbSet<Company> Companies { get; set; }

        public DbSet<Phone> Phones { get; set; }

        public DbSet<Student> Students { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            
            modelBuilder.Configurations.Add(new PersonMap());
            modelBuilder.Configurations.Add(new CompanyMap());
            modelBuilder.Configurations.Add(new StudentMap());

            modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
        }
    }

测试代码:

using (var context=new Context())
            {
                var person = new Person
                {
                    FirstName = "",
                    LastName=""
                };

                person.Student =new Student
                {
                    CollegeName = "test",
                    EnrollmentDate = DateTime.Now
                };
                context.People.Add(person);
                context.SaveChanges();
            }

posted @ 2015-09-20 07:50  古韵古风  阅读(287)  评论(0编辑  收藏  举报