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版本的还得等等了!
EntityFramework 6的更多相关文章
- EntityFramework Core Raw SQL
前言 本节我们来讲讲EF Core中的原始查询,目前在项目中对于简单的查询直接通过EF就可以解决,但是涉及到多表查询时为了一步到位就采用了原始查询的方式进行.下面我们一起来看看. EntityFram ...
- 恋爱虽易,相处不易:当EntityFramework爱上AutoMapper
剧情开始 为何相爱? 相处的问题? 女人的伟大? 剧情收尾? 有时候相识即是一种缘分,相爱也不需要太多的理由,一个眼神足矣,当EntityFramework遇上AutoMapper,就是如此,恋爱虽易 ...
- 关于这段时间学习 EntityFramework的 一点感悟
Ado.Net,用了N多年,Entity Framework也关注了很多年. 每当项目转型的时候,就花费大巴的时间,学习一番,潮流的东西. 这个Orm很多,这个EF很火,这么多年了,我还是不敢用,虽然 ...
- 采用EntityFramework.Extended 对EF进行扩展(Entity Framework 延伸系列2)
前言 Entity Framework 延伸系列目录 今天我们来讲讲EntityFramework.Extended 首先科普一下这个EntityFramework.Extended是什么,如下: 这 ...
- 一次修改闭源 Entity Provider 程序集以兼容新 EntityFramework 的过程
读完本文你会知道,如何在没有源码的情况下,直接修改一个 DLL 以去除 DLL 上的强命名限制,并在该程序集上直接添加你的“友元程序集(一种特殊的 Attribute,将它应用在程序集上,使得程序集内 ...
- ABP文档 - EntityFramework 集成
文档目录 本节内容: Nuget 包 DbContext 仓储 默认仓储 自定义仓储 特定的仓储基类 自定义仓储示例 仓储最佳实践 ABP可使用任何ORM框架,它已经内置了EntityFrame(以下 ...
- EntityFramework Core 1.1 Add、Attach、Update、Remove方法如何高效使用详解
前言 我比较喜欢安静,大概和我喜欢研究和琢磨技术原因相关吧,刚好到了元旦节,这几天可以好好学习下EF Core,同时在项目当中用到EF Core,借此机会给予比较深入的理解,这里我们只讲解和EF 6. ...
- 神马玩意,EntityFramework Core 1.1又更新了?走,赶紧去围观
前言 哦,不搞SQL了么,当然会继续,周末会继续更新,估计写完还得几十篇,但是我会坚持把SQL更新完毕,绝不会烂尾,后续很长一段时间没更新的话,不要想我,那说明我是学习新的技能去了,那就是学习英语,本 ...
- 问题记录:EntityFramework 一对一关系映射
EntityFramework 一对一关系映射有很多种,比如主键作为关联,配置比较简单,示例代码: public class Teacher { public int Id { get; set; } ...
- EntityFramework.Extended 支持 MySql
EntityFramework.Extended 默认不支持 MySql,需要配置如下代码: [DbConfigurationType(typeof(DbContextConfiguration))] ...
随机推荐
- codevs & vijos 爱在心中 - Tarjan
描述 “每个人都拥有一个梦,即使彼此不相同,能够与你分享,无论失败成功都会感动.爱因为在心中,平凡而不平庸,世界就像迷宫,却又让我们此刻相逢Our Home.” 在爱的国度里有N个人,在他们的心中都有 ...
- Java 多线程中的任务分解机制-ForkJoinPool,以及CompletableFuture
ForkJoinPool的优势在于,可以充分利用多cpu,多核cpu的优势,把一个任务拆分成多个“小任务”,把多个“小任务”放到多个处理器核心上并行执行:当多个“小任务”执行完成之后,再将这些执行结果 ...
- HDU 1796 How many integers can you find(容斥)题解
思路:二进制解决容斥问题,就和昨天做的差不多.但是这里题目给的因子不是质因子,所以我们求多个因子相乘时要算最小公倍数.题目所给的因数为非负数,故可能有0,如果因子为0就要删除. 代码: #includ ...
- POJ2528 Mayor's posters(线段树&区间更新+离散化)题解
题意:给一个区间,表示这个区间贴了一张海报,后贴的会覆盖前面的,问最后能看到几张海报. 思路: 之前就不会离散化,先讲一下离散化:这里离散化的原理是:先把每个端点值都放到一个数组中并除重+排序,我们就 ...
- The way to Go(6): Go程序的基本结构和要素
Reference: Github: Go Github: The way to Go Go程序的基本结构和要素 helloworld.go: package main import "fm ...
- Mui --- 页面之间的传值
A页面 mui.ajax('http://14.50.2.49:80/default/AppLogin?Prm=' + Prm, { data: {}, //dataType: 'json', typ ...
- Java中创建只读容器,同步容器
我们通过Collections.unmodifiableX来得到只读容器,因为容器被设为只读的,所以必须填入有意义的数据之后才进行设置 import java.util.ArrayList; impo ...
- python排序(插入排序) 从小到大顺序
def insert_sort(ilist): for i in range(len(ilist)): for j in range(i): if ilist[i] < ilist[j]: il ...
- django字段查询参数及聚合函数
字段查询是指如何指定SQL WHERE子句的内容.它们用作QuerySet的filter(), exclude()和get()方法的关键字参数. 默认查找类型为exact. 下表列出了所有的字段查询参 ...
- 【转】VC6在Win7下打开文件崩溃问题
http://www.cnblogs.com/Leon5/archive/2011/08/24/2152670.html 1.微软针对这个问题发布了一个补丁包.下载地址 2.下载之后是一个源码包,解压 ...