EF實體框架之CodeFirst一


對於SQL Server、MySql、Oracle等這些傳統的數據庫,基本都是關系型數據庫,都是體現實體與實體之間的聯系,在以前開發時,可能先根據需求設計數據庫,然后在寫Model和業務邏輯,對於Model類基本都是和表的字段對應着,而表中存的每條記錄又和類的實例對象對應着,有了這個對照關系,就是能不能只在一邊設計,在數據庫設計表或在VS中設計Model,然后直接生成另一邊,這樣就省了好多時間成本。於是有了ORM,Object Relation Mapping,對象關系映射。既然可以根據Model可以生成數據庫,數據庫也可以生成Model,Model、數據庫又是分離的,我們也可以根據Model生成不同類型(Sql Server\Oracle)數據庫,而不同類型的數據庫(Sql Server\Oracle)也可以生成同樣的Model,而它們共同的紐帶就是Mapping。

EF實體框架有3種類型,Data First、Model First、Code First。從今天起,將來的幾篇博客可能都是關於Code First的,可能有人會問,其他的呢?對於另外兩個我不打算花太多的時間,現在code first用的比較多,而且和其他兩個比來說更加方便簡單,code first沒有包含CSDL(Conceptual Schema Definition Language 概念架構定義語言)、SSDL(Store Schema Definition Language存儲架構定義語言)、MSL(Mapping Specification Language 映射規范語言)的映射定義,可是使用基於約定的映射。例如主鍵,只需要用Id命名屬性或以Id結尾,這種會自動映射到主鍵上。對於上面的CSDL、SSDL、MSL根據中文應該也能猜出一二來,其實CSDL概念架構定義語言,定義概念的嘛,當然是定義.Net類的,而SSDL存儲架構定義,既然是存儲,肯定是數據庫啊,所以它是描述表及其關系的結構。而MSL映射規范語言,當然是用來映射的,比如類中的Name屬性可能在數據庫定義的列名不是name,那怎么辦呢?這時有了MSL就好辦了,它就是用來描述映射關系的。

上面瞎逼逼半天,實際上今天是想大致演示下code first的用法,做簡單的增刪改查。

一、Model

首先是創建了一個控制台應用程序EFCodeFirstDemo,又創建了一個存放Model的類庫EFCodeFirstModels,以及一個與數據庫有關系的類庫EFCodeFirstDataAccess,算是三層架構中的DAL,至於BLL先不創建,只是簡單的演示。既然是code first,管理對象,那肯定要先有一個Model類,這里在EFCodeFirstDemo中定義了一個Student類。在Student類中使用約定定義StuId為主鍵,由於默認會把Id結尾的屬性作為主鍵,所以不用特性也可以。

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace EFCodeFirstModels
{
    public class Student
    {
        [Key]
        public string StuId { get; set; }

        public string Name { get; set; }

        public int Age { get; set; }

        public Student(string stuId, string name, int age)
        {
            this.StuId = stuId;
            this.Name = name;
            this.Age = age;
        }
        //定義無參數的構造函數主要是因為在通過DbSet獲取對象進行linq查詢時會報錯
        //The class 'EFCodeFirstModels.Student' has no parameterless constructor.
        public Student() { }

    }
}

二、DbContext數據庫上下文

DbContext數據庫上下文,定義了從實體對象到數據庫的映射,從數據庫中檢索數據,就要使用它。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity;
using EFCodeFirstModels;
using System.Configuration;


namespace EFCodeFirstDataAccess
{
    public class EFCodeFirstDbContext:DbContext
    {
        
        public EFCodeFirstDbContext():base("name=MyStrConn")
        {   
        }
        public DbSet<Student> Students { get; set; }
    }
}

在使用DbContext時要先通過NuGet添加EntityFramework,在類中引入System.Data.Entity,像上面的代碼中我們給DbContext指定了數據庫連接字符串,名字是MyStrConn,我們可以看下DbContext類的構造函數.

上面提供了幾種構造函數,今天主要看下第一個傳nameOrConnectionString和無參數的。如果不傳參數,它會自定將數據庫的名字命名為類庫名.類名,像上面的如果不使用無參數的構造函數會創建一個名為EFCodeFirstDataAccess.EFCodeFirstDbContext的數據庫。而我們的demo中是使用了參數的,參數的名是nameorConnectionString,注意是or那意味着有兩種情況,一種是name,一種是ConnectionString,在上面的參數是"name=XXX",這種是ConnectionString,既然是ConnectionString,那肯定有連接字符串,在哪呢?我開始是寫在了EFCodeFirstDataAccess類庫中,可以始終報錯,報初始化的錯誤,正確的是寫在控制台應用程序中的配置文件中,在配置文件App.config中添加結點。這里也要注意是要提供providerName,而且configSections必須是configuration的第一個結點,我剛才把connectionStrings添加到第一個也是提示錯誤。

  <connectionStrings>
    <add name="MyStrConn" providerName="System.Data.SqlClient" connectionString="Data Source=.;Initial Catalog=CodeFirstDb;Integrated Security=True"/>
  </connectionStrings>

我們也可以不使用ConnectionString,而是直接復制數據庫名,它會先找配置文件對於的連接字符串,如果未找到,則以它自己命名。

三、簡單操作

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using EFCodeFirstModels;
using EFCodeFirstDataAccess;

namespace EFCodeFirstDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            //using能及時釋放資源,例如數據庫連接異常,可以即使將上下文釋放
            using (var db=new EFCodeFirstDbContext())
            {
                Student stu = new Student("0001", "cuiyanwei", 25);
                db.Students.Add(stu);
                db.SaveChanges();
                string name= db.Students.Select(p => p.Name).FirstOrDefault().ToString() ;
                Console.WriteLine(name);

                Student stu1 = db.Students.Where(p=>p.StuId=="0001").FirstOrDefault() ;
                stu1.Name = "CYW";
                db.SaveChanges();

                name = db.Students.Select(p => p.Name).FirstOrDefault().ToString();
                Console.WriteLine(name);
               
            }
            Console.ReadLine();
            
        }
    }
}

在上面代碼中,主要是先新增一個Student對象然后插入數據庫,打印輸出此時的name,然后通過數據庫上下文找到StuId=0001的學生,將name更改為CYW,

保存到數據庫再次打印數據name,從打印結果我們可以看到name最后是CYW,數據庫中最后的結果也是CYW。通過Profiler也能查看到sql執行的過程。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM