Entity Framework代码优先(Code First)模式

目录
  • 一、Code First 代码优先
  • 二、创建或生成Model代码
    • 1、从数据库生成Model代码
    • 2、手工创建Model代码
  • 三、配置文件
  • 四、操作
    • 1、添加单个实体,Add
    • 2、修改
    • 3、删除,Remove
  • 五、查询
    • 1、Load():
    • 2、ToList():
    • 3、Find():
    • 4、Single()、SingleOrDefault()、First()等:
  • 六、直接执行SQL语句
    • 1、在实体上运行SQL命令,
    • 2、在Database属性上运行SQL命令

一、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

到此这篇关于Entity Framework代码优先(Code First)的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Entity Framework使用Code First模式管理事务

    一.什么是事务 处理以数据为中心的应用时,另一个重要的话题是事务管理.ADO.NET为事务管理提供了一个非常干净和有效的API.因为EF运行在ADO.NET之上,所以EF可以使用ADO.NET的事务管理功能. 当从数据库角度谈论事务时,它意味着一系列操作被当作一个不可分割的操作.所有的操作要么全部成功,要么全部失败.事务的概念是一个可靠的工作单元,事务中的所有数据库操作应该被看作是一个工作单元. 从应用程序的角度来看,如果我们有多个数据库操作被当作一个工作单元,那么应该将这些操作包裹在一个事务中

  • Entity Framework使用Code First模式管理存储过程

    在EF中使用存储过程和使用视图是很相似的,一般会使用Database对象上的两个方法:SqlQuery和ExecuteSqlCommand.为了从存储过程中读取很多数据行,我们只需要定义一个类,我们会将检索到的所有数据行物质化到该类实例的集合中.比如,从下面的存储过程读取数据: CREATE PROCEDURE [dbo].[SelectBooks] @BookTypeName AS NVARCHAR(10) AS BEGIN select B.Name,B.Author,B.Publicati

  • Entity Framework使用Code First的实体继承模式

    目录 一.TPT继承模式 1.Person类 2.使用数据迁移创建数据库 3.填充数据 二.TPH模式 1.创建有继承关系的实体类 2.创建数据上下文 3.使用数据迁移创建数据库 4.不使用默认生成的区别多张表的类型 5.填充数据 6.查询数据 三.TPC模式 1.创建实体类 2.配置数据上下文 3.使用数据迁移生成数据库 4.填充数据 Entity Framework的Code First模式有三种实体继承模式 1.Table per Type (TPT)继承 2.Table per Clas

  • Entity Framework使用Code First模式管理数据库

    一.管理数据库连接 1.使用配置文件管理连接之约定 在数据库上下文类中,如果我们只继承了无参数的DbContext,并且在配置文件中创建了和数据库上下文类同名的连接字符串,那么EF会使用该连接字符串自动计算出数据库的位置和数据库名.比如,我们的数据库上下文定义如下: using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Text; usin

  • Entity Framework使用Code First模式管理视图

    一.什么是视图 视图在RDBMS(关系型数据库管理系统)中扮演了一个重要的角色,它是将多个表的数据联结成一种看起来像是一张表的结构,但是没有提供持久化.因此,可以将视图看成是一个原生表数据顶层的一个抽象.例如,我们可以使用视图提供不同安全的级别,也可以简化必须编写的查询,尤其是我们可以在代码中的多个地方频繁地访问使用视图定义的数据.EF Code First模式现在还不完全支持视图,因此我们必须使用一种变通的方法.这种方法是:将视图真正看成是一张表,让EF定义这张表,然后在删除它,最后再创建一个

  • Entity Framework代码优先(Code First)模式

    目录 一.Code First 代码优先 二.创建或生成Model代码 1.从数据库生成Model代码 2.手工创建Model代码 三.配置文件 四.操作 1.添加单个实体,Add 2.修改 3.删除,Remove 五.查询 1.Load(): 2.ToList(): 3.Find(): 4.Single().SingleOrDefault().First()等: 六.直接执行SQL语句 1.在实体上运行SQL命令, 2.在Database属性上运行SQL命令 一.Code First 代码优先

  • Entity Framework代码优先Code First入门

    CodeFirst是EntityFramework 4.1后新增的一种映射方式,在这种方式下,开发人员只需要编写代码,由ORM框架自动动创建模型和数据库,数据库则可看作类似于XML一样序列化的方式,非常简洁(由于开发人员可以无需关心数据库的具体结构,最初也有叫做CodeOnly的). 下面就以一个简单的例子演示一下如何使用CodeFirst. 一.用Nuget添加EntityFramework框架的引用. 二.编写代码 static void Main(string[] args) { usin

  • Entity Framework模型优先与实体对象查询

    目录 一.概念: 1.EF6 可实现的功能: 二.安装Entity Framework6 1.VS2019 Installer安装“Entity Framework6 工具” 2.通过Nuget安装“Entity Framework”: 三.新建ObjectContext 和EntityObject 1.“根据模型生成的数据库”的设计器功能实现ModelFirst. 四.实体对象查询:linq to Entities 1.使用lambda表达式查询 2.执行存储过程(通过“添加”-----”函数

  • Entity Framework使用DataBase First模式实现增删改查

    一.新建控制台应用程序,然后右键->添加新建项,选择数据里面的实体数据模型: 然后点击添加 二.选择来自数据库的EF设计器,并点击下一步 三.在实体数据模型向导界面选择要使用的数据连接,或者点击新建连接按钮创建新的连接,这里选择已有的连接,并点击下一步: 四.选择实体框架6.0,点击下一步: 五.选择要操作的表,并点击完成: 六.查看生成的项目结构 自动添加了EntityFramework的引用.同时会在项目的根目录下面生成一个package文件夹: package文件夹里面存放的是与Entit

  • 在Code First模式中自动创建Entity模型

    之前我在博客文章中介绍过如何使用Code First来创建数据库,通过CodeFirst的方式,可以大幅的减少开发人员的工作量,比传统的先创建库再ORM的方式简单了不少.但是,很多时候,特别是一些MIS系统,我们会涉及到大量的实体类型,类似如下所示: public class DbContext : System.Data.Entity.DbContext { public DbContext() : base("name=DefaultConnection") { } public

随机推荐