Entity Framework代码优先(Code First)模式
作者:springsnow 发布时间:2022-07-28 05:31:05
一、Code First 代码优先
DbContext可以用于数据库优先,代码优先和模型优先的开发。
DbContext主要包含一组非常易于使用的API。该API由ObjectContext公开。这些API还允许我们使用ObjectContext不允许的Code First方法。
DbContext只是ObjectContext包装器,可以说它是ObjectContext的轻量级替代方案。
1、从ObjectContext转化到DbContext
DbContext ctx= new DbContext(ctxObj , true);
EF6支持Oracle ODT 12C Release 3 (net4.5)以上
二、创建或生成Model代码
1、从数据库生成Model代码
可以使用高级的反向工程工具POCO生成器模板(收费)。https://marketplace.visualstudio.com/items?itemName=SimonHughes.EntityFrameworkReversePOCOGenerator
一般使用Visual Studio EF 6工具附带的不太高级的“"Code First from Database" ”功能。
实体框架提供了一种对现有数据库使用代码优先方法的简便方法。它将为现有数据库中的所有表和视图创建实体类,并使用数据注释属性和Fluent API对其进行配置。
要将代码优先用于现有数据库,请在Visual Studio中右键单击您的项目->添加->新建项。
在“添加新项”对话框中选择“ADO.NET实体数据模型”,并指定模型名称(这将是上下文类名称),然后单击“添加”。
这将打开“实体数据模型”向导,如下所示。从数据库选项中选择代码优先,然后单击下一步。
现在,为现有数据库选择数据连接。如果下拉列表不包括与现有数据库的连接,请为您的数据库创建一个新连接。单击下一步继续。
现在,选择要为其生成类的表和视图,然后单击“完成”。
这将为您的数据库表和视图生成所有实体类,如下所示。
例如,它将创建以下上下文类,该上下文类使用Fluent API根据数据库配置实体类。
namespace EFDemo
{
using System;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
public partial class SchoolContext : DbContext
{
public SchoolContext()
: base("name=SchoolContext2")
{
}
public virtual DbSet<Course> Courses { get; set; }
public virtual DbSet<Standard> Standards { get; set; }
public virtual DbSet<Student> Students { get; set; }
public virtual DbSet<StudentAddress> StudentAddresses { get; set; }
public virtual DbSet<Teacher> Teachers { get; set; }
public virtual DbSet<View_StudentCourse> View_StudentCourse { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Course>()
.Property(e => e.CourseName)
.IsUnicode(false);
modelBuilder.Entity<Course>()
.HasMany(e => e.Students)
.WithMany(e => e.Courses)
.Map(m => m.ToTable("StudentCourse").MapLeftKey("CourseId").MapRightKey("StudentId"));
modelBuilder.Entity<Standard>()
.Property(e => e.StandardName)
.IsUnicode(false);
modelBuilder.Entity<Standard>()
.Property(e => e.Description)
.IsUnicode(false);
modelBuilder.Entity<Standard>()
.HasMany(e => e.Students)
.WithOptional(e => e.Standard)
.WillCascadeOnDelete();
modelBuilder.Entity<Standard>()
.HasMany(e => e.Teachers)
.WithOptional(e => e.Standard)
.WillCascadeOnDelete();
modelBuilder.Entity<Student>()
.Property(e => e.StudentName)
.IsUnicode(false);
modelBuilder.Entity<Student>()
.Property(e => e.RowVersion)
.IsFixedLength();
modelBuilder.Entity<Student>()
.HasOptional(e => e.StudentAddress)
.WithRequired(e => e.Student)
.WillCascadeOnDelete();
modelBuilder.Entity<StudentAddress>()
.Property(e => e.Address1)
.IsUnicode(false);
modelBuilder.Entity<StudentAddress>()
.Property(e => e.Address2)
.IsUnicode(false);
modelBuilder.Entity<StudentAddress>()
.Property(e => e.City)
.IsUnicode(false);
modelBuilder.Entity<StudentAddress>()
.Property(e => e.State)
.IsUnicode(false);
modelBuilder.Entity<Teacher>()
.Property(e => e.TeacherName)
.IsUnicode(false);
modelBuilder.Entity<Teacher>()
.HasMany(e => e.Courses)
.WithOptional(e => e.Teacher)
.WillCascadeOnDelete();
modelBuilder.Entity<View_StudentCourse>()
.Property(e => e.StudentName)
.IsUnicode(false);
modelBuilder.Entity<View_StudentCourse>()
.Property(e => e.CourseName)
.IsUnicode(false);
}
}
}
EF 6有用的设计时实用程序:https://marketplace.visualstudio.com/items?itemName=ErikEJ.EntityFramework6PowerToolsCommunityEdition
2、手工创建Model代码
方式1、使用标注
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
namespace CodeFirst.Model
{
///
/// 目的景点类
///
[Table("DESTINATIONS", Schema = "PAMS")]
public class Destination
{
[Column("DESTINATIONID", TypeName = "INT")]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int DestinationId { get; set; }
[Column("NAME")]
public string Name { get; set; }
[Column("COUNTRY")]
public string Country { get; set; }
[Column("DESCRIPTION")]
public string Description { get; set; }
[Column("PHOTO")]
public byte[] Photo { get; set; }
public virtual List Lodgings { get; set; } //景点带有多个住宿点
}
///
/// 住宿类
///
[Table("LODGINGS", Schema = "PAMS")]
public class Lodging
{
[Column("LODGINGID", TypeName = "INT")]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int LodgingId { get; set; }
[Column("NAME")]
public string Name { get; set; }
[Column("OWNER")]
public string Owner { get; set; }
[Column("TARDESTINATIONID", TypeName = "INT")]
public int? DestinationID { get; set; }
[ForeignKey("DestinationID")]
public Destination Destination { get; set; }
}
///
/// 度假村类,继承自住宿类
///
public class Resort : Lodging
{
[Column("ENTERTAINMENT")]
public string Entertainment { get; set; }
}
///
/// 旅馆类,继承自住宿类
///
public class Hostel : Lodging
{
[Column("MAXROOM", TypeName = "INT")]
public int? MaxRoom { get; set; }
}
}
方式2:使用模板Builder“配置”属性和关系
using CodeFirst.Model;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration;
namespace CodeFirst.DataAccess
{
public class BreakAwayContext : DbContext
{
public DbSet Destinations { get; set; }
public DbSet Lodgings { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new DestinationMap());
modelBuilder.Configurations.Add(new LodgingMap());
}
}
public class DestinationMap : EntityTypeConfiguration
{
public DestinationMap()
{
this.HasKey(t => t.DestinationId);
Property(d => d.Name).IsRequired();
Property(d => d.Description).HasMaxLength(500);
}
}
public class LodgingMap : EntityTypeConfiguration
{
public LodgingMap()
{
this.HasKey(t => t.LodgingId);
Property(d => d.Name).IsRequired();
Property(d => d.Owner).HasMaxLength(500);
this.Map(d => d.Requires("TYPE").HasValue("Standard"));
this.Map(d => d.Requires("TYPE").HasValue("Resort"));
this.Map(d => d.Requires("TYPE").HasValue("Hostel"));
}
}
}
三、配置文件
<connectionStrings>
<add name="BreakAwayContext" connectionString="Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=BreakAway;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False" providerName="System.Data.SqlClient"/>
</connectionStrings>
四、操作
1、添加单个实体,Add
var destination = new CodeFirst.Model.Destination
{
Country = "Indonesia",
Description = "EcoTourism at its best in exquisite Bali",
Name = "Bali"
};
using (var context = new CodeFirst.DataAccess.BreakAwayContext())
{
if (context.Destinations.Count((t => t.Name == "Bali") < 1)
{
context.Destinations.Add(destination);
context.SaveChanges();
}
}
2、修改
using (var context = new CodeFirst.DataAccess.BreakAwayContext())
{
var canyon = (from d in context.Destinations where d.Name == "Bali" select d).Single();
canyon.Description = "227 mile long canyon.";
//context.Entry(canyon )=EntityState.Modified;
context.SaveChanges();
}
3、删除,Remove
var toDelete = new CodeFirst.Model.Destination { Name = "Bali" };
context.Destinations.Attach(toDelete); //attach
context.Destinations.Remove(toDelete);
context.SaveChanges();
五、查询
1、Load():
把数据加载到内存,使用实体的Local属性访问。(LINQ写法,同foreach)
using (var context = new CodeFirst.DataAccess.BreakAwayContext())
{
var query = from d in context.Destinations where d.Country == "Australia" select d;
query.Load();// foreach 也可以
var count = context.Destinations.Local.Count;
}
2、ToList():
一次性从数据库中查出数据
var Invoices=ctx.Invoie.ToList();
foreach(var result in Onvoices)
{.}
3、Find():
根据键值先从内存中查询,内存中没有才查询数据库。
var destination = context.Destinations.Find(4);
4、Single()、SingleOrDefault()、First()等:
可根据条件直接从数据库查。
var destination = context.Destinations.SingleOrDefault(d => d.Name == "Bali");
六、直接执行SQL语句
1、在实体上运行SQL命令,
SQL查询:SqlQuery
DbSqlQuery c = ctx.Lodging.SqlQuery("select * from.."); //EF跟踪返回的对象。
2、在Database属性上运行SQL命令
1、SQL查询:Database.SqlQuery
IEnumerable a = ctx.Database.SqlQuery("Select * from.."); //可直接转为定义的实体类型,任何类型,EF不跟踪
2、执行SQL命令:Database.ExecuteSqlCommand
ctx.Database.ExecuteSqlCommand("delete from pams.DESTINATIONS where Name='Bali'");//直接执行sql
来源:https://www.cnblogs.com/springsnow/p/13230074.html


猜你喜欢
- 密封类和密封接口是 Kotlin 中允许创建受限类层次结构的两个特性。这两个构造用于定义一组有限的可能子类型,并防止在声明的层次结构之外定义
- 目录Java 基础语法中的逻辑控制一、逻辑控制语句1. 顺序结构2. 分支结构3. 循环结构二、输入输出方式1. 输出到控制台2. 从键盘输
- IDEA时跳转到.class的解决项目背景:jdk1.8软件环境:IDEA问题:两个不同的项目,在A项目中写了一个实体类。B项目中引用。我想
- 本文实例讲述了Java使用Random类生成随机数。分享给大家供大家参考,具体如下:一 代码import java.util.Random;
- 最近一段时间在研究OAuth2的使用,想整个单点登录,从网上找了很多demo都没有实施成功,也许是因为压根就不懂OAuth2的原理导致。有那
- 最近研究OpenCV想用java进行开发,因此研究了一下怎么在Eclipse中配置基于java的Opencv.第一步:先到OpenCV官网下
- 1、SDK下载很慢。配置SDK代理,速度像飞一样。建议先把20-24下完,不然后面遇到很多问题。2、support-v7的问题例如res\v
- Android 中Activity 之间传递参数1.传递简单数据在A Activity中findViewById(R.id.startBAc
- 程序触发鼠标、键盘事件是C#程序设计中比较常见的功能,本文实例展示了C#中winform实现自动触发鼠标、键盘事件的方法,有不错的实用价值。
- Android Studio连接手机设备教程,供大家参考,具体内容如下一、ADB环境配置1.查看自己Android Studio配置的sdk
- 一、题目描述题目实现:使用网络编程时,需要通过Socket传递对象。二、解题思路创建一个类:Student,实现序列化Student类包含两
- Step1: 安装JDK并配置环境变量;Step2: 安装Gradle进入点击打开链接官网首页点击install gra
- 本文实例为大家分享了C#简单爬虫案例,供大家参考,具体内容如下using System;using System.Collections.G
- 你是否遇到过应用程序性能下降的问题?有没有想过提升Spring性能?如果是这样 - 那么这篇文章绝对适合你。在这里,我们将谈论使用超级强大和
- 本文实例为大家分享了Android学习之Broadcast的使用方法,供大家参考,具体内容如下实现开机启动提示网络的广播package co
- 1、Spring的事务管理主要包括3个接口TransactionDefinition:封装事务的隔离级别,超时时间,是否为只读事务和事务的传
- 现在软件或者网页的并发量越来越大了,大量请求直接操作数据库会对数据库造成很大的压力,处理大量连接和请求就会需要很长时间,但是实际中百分之80
- 在Android的应用框架中,ActivityManagerService是非常重要的一个组件,尽管名字叫做ActivityManagerS
- DataTable可以通过RowStatus来判断状态是否发生了改变。但是有些时候我们希望在行状态即使为Modified的情况下也不要提示内
- Android 双击Back键退出应用的实现方法实现原理:双击退出程序的原理无非就是设置一个退出标识(询问是否退出),如果改变了这个标识(确