EF6 code first


.EF6

3.1初步目录及说明

     下面是用VS2013开发环境创建的项目:

    

     说明:控制台项目类型,安装EF版本为6.1.3, 数据库连接字符串配置:     

  <connectionStrings>
    <add name="DefaultConnection"
         connectionString="Data Source=.;Initial Catalog=TestDB;UID=sa;PWD=123456"
      providerName="System.Data.SqlClient" />
  </connectionStrings>

      EFContext.cs代码:

复制代码
using Consoles.EF6.Models;
using System.Data.Entity;

namespace Consoles.EF6.Repositories
{
    public class EFContext : DbContext
    {
        public EFContext() : base("DefaultConnection") { }

        public DbSet<Category> Categories { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Category>().HasKey(k => k.CategoryId) //设置主键
                .Property(q => q.CategoryName).IsRequired();//设置不能为空
        }
    }
}
复制代码

       注:

          a.数据库上下文构造方法,继承基类,其参数是DefaultConnection,配置的数据库连接字符串中name值要一致;

             如果name值和上下文类名(EFContext)一致的话,上下文类的构造方法也可以省略.

          b.为了保持实体类"干净",不使用DataAnnotations数据注解特性,改为Fluent API配置方式.当然有些已经默认了,我们照样进行配置.

             如:属性为Id(字母不分大小写)或为类名+Id,它会默认为主键,但我们也配置:Entity<Category>().HasKey(k => k.CategoryId)

             疑问:这种两种方式,到底采用那种好呢?这个……我表示无语,你自个看那个爽啦。

3.2示例一

      Category.cs代码:

复制代码
namespace Consoles.EF6.Models
{
    public class Category
    {
        public int CategoryId { get; set; }
        public string CategoryName { get; set; }
        public string Description { get; set; }
    }
}
复制代码

      Program.cs代码:

复制代码
using Consoles.EF6.Models;
using Consoles.EF6.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Entity.Migrations;

namespace Consoles.EF6
{
    class Program
    {
        static void Main(string[] args)
        {
            #region 示例一
            using (var db = new EFContext())
            {
                var categories = new List<Category>
                {
                    new Category(){ CategoryName="Mobile",Description="手机大类"},
                    new Category(){ CategoryName="Computer",Description="电脑大类"}
                };

                //AddOrUpdate:根据指定列,相同就更新,不相同就添加
                categories.ForEach(list => db.Categories.AddOrUpdate(c => c.CategoryId, list));
                db.SaveChanges();

                //var query = db.Categories;
                 var query = from c in db.Categories select c;

                //遍历输出
                foreach (var item in query)
                {
                    Console.WriteLine("类别:{0};说明:{1}", item.CategoryName, item.Description);
                }
            }
            #endregion

            Console.ReadKey();
        }
    }
}
复制代码

       运行结果:
      

       查看数据库:

      

3.3示例二

      我们添一个Subcategory.cs,其代码:

复制代码
namespace Consoles.EF6.Models
{
    public class Subcategory
    {
        public int SubcategoryId { get; set; }
        public string SubcategoryName { get; set; }

        public int CategoryId { get; set; }
        public Category Category { get; set; }
    }
}
复制代码

      再修改Category.cs代码:

复制代码
using System.Collections.Generic;

namespace Consoles.EF6.Models
{
    public class Category
    {
        public int CategoryId { get; set; }
        public string CategoryName { get; set; }
        public string Description { get; set; }

        public ICollection<Subcategory> Subcategories { get; set; }
    }
}
复制代码

      设计关系为:大类Category:子类Subcategory=1:N。子类必须属于某一个大类,也就是外键不能为空。配置Fluent API     

复制代码
using Consoles.EF6.Models;
using System.Data.Entity;

namespace Consoles.EF6.Repositories
{
    public class EFContext : DbContext
    {
        public EFContext() : base("DefaultConnection") { }

        public DbSet<Category> Categories { get; set; }
        public DbSet<Subcategory> Subcategories { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Category>().HasMany(s => s.Subcategories)
                .WithRequired(c => c.Category).HasForeignKey(f=>f.CategoryId);
            modelBuilder.Entity<Category>().HasKey(k => k.CategoryId);
            modelBuilder.Entity<Category>().Property(p => p.CategoryName).HasMaxLength(20);

            modelBuilder.Entity<Subcategory>().HasKey(K => K.SubcategoryId);
            modelBuilder.Entity<Subcategory>().Property(p => p.SubcategoryName).IsRequired();
        }
    }
}
复制代码

       Program.cs代码:

复制代码
using Consoles.EF6.Models;
using Consoles.EF6.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Entity.Migrations;

namespace Consoles.EF6
{
    class Program
    {
        static void Main(string[] args)
        {
            #region 示例二
            using (var db = new EFContext())
            {
                var categories = new List<Category>
                {
                    new Category(){ CategoryName="Mobile",Description="手机大类"},
                    new Category(){ CategoryName="Computer",Description="电脑大类"}
                };
                categories.ForEach(list => db.Categories.AddOrUpdate(c => c.CategoryId, list));
                db.SaveChanges();

                var subcategories = new List<Subcategory>
                {
                    new Subcategory(){ SubcategoryName="2G",Category=db.Categories.Single(c=>c.CategoryName=="Mobile")},
                    new Subcategory(){ SubcategoryName="3G",Category=db.Categories.Single(c=>c.CategoryName=="Mobile")},
                    new Subcategory(){ SubcategoryName="4G",Category=db.Categories.Single(c=>c.CategoryName=="Mobile")},
                    new Subcategory(){ SubcategoryName="Desktop",Category=db.Categories.Single(c=>c.CategoryName=="Computer")},
                    new Subcategory(){ SubcategoryName="Tablet ",Category=db.Categories.Single(c=>c.CategoryName=="Computer")}        
                };
                subcategories.ForEach(list => db.Subcategories.AddOrUpdate(c => c.SubcategoryId, list));
                db.SaveChanges();

                var query = from c in db.Categories select c;
                foreach (var item in query)
                {
                    Console.WriteLine("类别:{0};说明:{1}", item.CategoryName, item.Description);
                }
            }
            #endregion

            Console.ReadKey();
        }
    }
}
复制代码

        查看数据库:

        

        嘎嘎! 一对多关系OK!Subcategories表的外键也不为空!

3.4示例三

        我们再添加一个Product.cs,其代码:

复制代码
using System.Collections.Generic;

namespace Consoles.EF6.Models
{
    public class Product
    {
        public int ProductId { get; set; }
        public string ProductName { get; set; }

        public ICollection<Subcategory> Subcategories { get; set; }
    }
}
复制代码

      再修改Subcategory.cs: 

复制代码
using System.Collections.Generic;

namespace Consoles.EF6.Models
{
    public class Subcategory
    {
        public int SubcategoryId { get; set; }
        public string SubcategoryName { get; set; }

        public int CategoryId { get; set; }
        public Category Category { get; set; }

        public ICollection<Product> Products { get; set; }
    }
}
复制代码

     修改EFContext.cs:

复制代码
using Consoles.EF6.Models;
using System.Data.Entity;

namespace Consoles.EF6.Repositories
{
    public class EFContext : DbContext
    {
        public EFContext() : base("DefaultConnection") { }

        public DbSet<Category> Categories { get; set; }
        public DbSet<Subcategory> Subcategories { get; set; }
        public DbSet<Product> Products { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Category>().HasMany(s => s.Subcategories)
                .WithRequired(c => c.Category).HasForeignKey(f => f.CategoryId);
            modelBuilder.Entity<Category>().HasKey(k => k.CategoryId);
            modelBuilder.Entity<Category>().Property(p => p.CategoryName).HasMaxLength(20);

            modelBuilder.Entity<Subcategory>().HasKey(K => K.SubcategoryId);
            modelBuilder.Entity<Subcategory>().Property(p => p.SubcategoryName).IsRequired();

            modelBuilder.Entity<Product>().HasKey(k => k.ProductId);
            modelBuilder.Entity<Product>().Property(p => p.ProductName).HasMaxLength(120);

            modelBuilder.Entity<Subcategory>()
             .HasMany(c => c.Products).WithMany(p => p.Subcategories)
             .Map(t => t.MapLeftKey("SubCategoryId")
             .MapRightKey("ProductId")
             .ToTable("SubcategoryProduct"));
        }
    }
}
复制代码

        查看数据库:

       

3.5初始化数据

        前面我们是在Main方法写的模拟数据代码,是不是不太好?在“第05章”文中,我也说过有预留的问题,在这补充一下。

        添加SampleData.cs,其代码:

复制代码
using Consoles.EF6.Models;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Data.Entity.Migrations;

namespace Consoles.EF6.Repositories
{
    public class SampleData : DropCreateDatabaseIfModelChanges<EFContext>
    {
        protected override void Seed(EFContext db)
        {
            var categories = new List<Category>
                {
                    new Category(){ CategoryName="Mobile",Description="手机大类"},
                    new Category(){ CategoryName="Computer",Description="电脑大类"}
                };
            categories.ForEach(list => db.Categories.AddOrUpdate(c => c.CategoryId, list));
            db.SaveChanges();

            var subcategories = new List<Subcategory>
                {
                    new Subcategory(){ SubcategoryName="2G",Category=db.Categories.Single(c=>c.CategoryName=="Mobile")},
                    new Subcategory(){ SubcategoryName="3G",Category=db.Categories.Single(c=>c.CategoryName=="Mobile")},
                    new Subcategory(){ SubcategoryName="4G",Category=db.Categories.Single(c=>c.CategoryName=="Mobile")},
                    new Subcategory(){ SubcategoryName="Desktop",Category=db.Categories.Single(c=>c.CategoryName=="Computer")},
                    new Subcategory(){ SubcategoryName="Tablet ",Category=db.Categories.Single(c=>c.CategoryName=="Computer")}        
                };
            subcategories.ForEach(list => db.Subcategories.AddOrUpdate(c => c.SubcategoryId, list));
            db.SaveChanges();
        }
    }
}
复制代码

     注:关于多对多关系的数据添加,参加"第05章"示例!   

     添加配置节点:

    

         这样只要有访问数据库时,就会初始化数据了,如:  

复制代码
using Consoles.EF6.Models;
using Consoles.EF6.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Entity.Migrations;

namespace Consoles.EF6
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var db = new EFContext())
            {
                var query = from c in db.Categories select c;
                foreach (var item in query)
                {
                    Console.WriteLine("类别:{0};说明:{1}", item.CategoryName, item.Description);
                }
            }

            Console.ReadKey();
        }
    }
}
复制代码

         我们并没在程序显式的代码中执行SampleData里的Seed方法,通过配置文件即可(在不需要时,也可以disableDatabaseInitialization关闭).

4.EF7

4.1目录及说明

    下面是用VS2015开发环境创建的项目:

    

    说明:ASP.NET 5版的WebApi项目类型;

    依赖和Commands配置:

   

    commands之ef是迁移用的,这在“第06章”已经介绍过,这里会略过。  

4.2示例

    由于EF7暂时不直接支持多对多实体关系(也可能我了解有限),所以这里举例一对多。

    Category.cs代码: 

复制代码
using System.Collections.Generic;

namespace WebApies.EF7.Models
{
    public class Category
    {
        public int CategoryId { get; set; }
        public string CategoryName { get; set; }
        public string Description { get; set; }

        public ICollection<Subcategory> Subcategories { get; set; }
    }
}
复制代码

     Subcategory.cs代码:

复制代码
namespace WebApies.EF7.Models
{
    public class Subcategory
    {
        public int SubcategoryId { get; set; }
        public string SubcategoryName { get; set; }

        public int CategoryId { get; set; }
        public Category Category { get; set; }
    }
}
复制代码

     EFContext.cs代码:

复制代码
using Microsoft.Data.Entity;
using WebApies.EF7.Models;
using Microsoft.Data.Entity.Metadata;

namespace WebApies.EF7.Repositories
{
    public class EFContext : DbContext
    {
        public DbSet<Category> Categories { get; set; }
        public DbSet<Subcategory> Subcategories { get; set; }

        protected override void OnConfiguring(DbContextOptions options)
        {
            options.UseSqlServer(
                "Server=(localdb)\\mssqllocaldb;Database=TestDB;Trusted_Connection=True;MultipleActiveResultSets=true");
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Category>().HasMany(C => C.Subcategories).WithOne().ForeignKey(f=>f.CategoryId);
            modelBuilder.Entity<Category>().Key(k => k.CategoryId);
            modelBuilder.Entity<Category>().Property(p => p.CategoryName).MaxLength(20);

            modelBuilder.Entity<Subcategory>().Key(K => K.SubcategoryId);
            modelBuilder.Entity<Subcategory>().Property(p => p.SubcategoryName).Required();
        }
    }
}
复制代码

        迁移完毕后,查看数据库:

       

        注:MaxLength没有起作用!(完整版的sqlserver是正常的)

        基架模板代码创建:

          

        此时目录:

       

        这是T4模板代码,这个MVC版的,webapi版本的还得等等了!

5.小结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值