EF6 code first
来源:互联网 发布:航空票务网站源码 编辑:程序博客网 时间:2024/05/17 22:36
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.小结
- EF6 code first
- EF6+MySql code first
- EF6 Code First for MultiContext
- MVC 5 的 EF6 Code First 入门
- Sqlite之Code First(EF6)
- 让Vs2013 完美支持EF6.1 Code First with Oracle
- MVC5与EF6 Code First 第一个入门完整实例教程
- MVC5与EF6 Code First 第一个入门完整实例教程
- EF6 调用SQLite(适用于code first,非code first参考官方配置文件)
- [01] 使用 MVC 5 的 EF6 Code First 入门 系列:建立一个EF数据模型
- [02] 使用 MVC 5 的 EF6 Code First 入门 系列:实现基本的CRUD功能
- [03] 使用 MVC 5 的 EF6 Code First 入门 系列:排序、筛选和分页
- [13]使用 MVC 5 的 EF6 Code First 入门 系列:补充:Deploy to Azure
- 使用MVC 5的EF6 Code First入门系列:为ASP.NET MVC应用程序处理并发
- MVC5中EF6 Code First启动慢及间隙变慢优化的实践经验
- 亲授MVC5中EF6 Code First启动慢及间隙变慢优化的实践经验
- MVC中code first方式开发,数据库的生成与更新(Ef6)
- [C#.NET][Entity Framework] Code First - Reverse engineering from an existing database at EF6.1.0
- Android-对图片缓存的剖析
- sqoop数据导入导出
- ios属性关键字(assign、copy、retain、nonatomic)
- 复杂网络笔记-R语言
- android Handler机制的学习
- EF6 code first
- git pro 学习笔记---第二章,git的基础
- JavaScript面相对象编程实践
- Xtrabackup备份恢复
- 【CF 708C】Centroids(树型DP)
- Xcode7.3 编译不提示类名
- 插件描述:jCountdown倒计时插件jQuery
- Android——RxJava开启响应式编程时代
- 单点触控、多点触控和自定义控件的使用