• EntityFramework 6


    3.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版本的还得等等了!

  • 相关阅读:
    MySQL 一致性读 深入研究
    Operating System Error Codes
    5分钟了解MySQL5.7的Online DDL雷区
    pt-osc原理、限制、及与原生online-ddl比较
    学习笔记:Rick's RoTs -- Rules of Thumb for MySQL
    学习笔记:The Best of MySQL Forum
    学习笔记:Analyze MySQL Performance及慢日志的开启
    MySQL: Building the best INDEX for a given SELECT
    学习笔记:ALTERing a Huge MySQL Table
    Google common_schema 2.2 documentation
  • 原文地址:https://www.cnblogs.com/zxtceq/p/5346346.html
Copyright © 2020-2023  润新知