• Entity Framework(03):Code First基础


    一、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中右键单击您的项目->添加->新建项。


    code first for an existing database

    在“添加新项”对话框中选择“ADO.NET实体数据模型”,并指定模型名称(这将是上下文类名称),然后单击“添加”。

    code first for an existing database

    这将打开“实体数据模型”向导,如下所示。从数据库选项中选择代码优先,然后单击下一步。

    code first for an existing database

    现在,为现有数据库选择数据连接。如果下拉列表不包括与现有数据库的连接,请为您的数据库创建一个新连接。单击下一步继续。

    code first for an existing database

    现在,选择要为其生成类的表和视图,然后单击“完成”。

    code first for an existing database

    这将为您的数据库表和视图生成所有实体类,如下所示。

    code first for an existing database

    例如,它将创建以下上下文类,该上下文类使用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

    image

    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
  • 相关阅读:
    Spring快速开启计划任务
    一张图告诉你什么是系统架构师
    一张图搞清楚Java异常机制
    Spring Cloud配置中心内容加密
    Spring Cloud配置中心高可用搭建
    Spring Cloud动态刷新配置信息
    Spring Boot实现热部署
    Spring Boot集成Mybatis双数据源
    (1)python tkinter-窗体
    (1)html基础
  • 原文地址:https://www.cnblogs.com/springsnow/p/13230074.html
Copyright © 2020-2023  润新知