Entityframework的簡單應用


 

 

項目中使用EntityFramework

  

項目代碼:http://yunpan.cn/cKAw3sSJWQwUX  提取碼 871c

文筆不好,技術也差。來這就是來提高自己的,歡迎批評。最后還留下一個小問題,如果你知道的話可以告訴我,謝謝。(郵箱:jin_wangjia@163.com)

 

前言 1

1. 建立解決方案項目結構 1

2. 導入EntityFramework類庫 1

3. 編寫實體類 1

4. 編輯連接字符串 3

5. 編寫BaseBLL類 3

6. 編寫業務處理超類 4

7. 編寫業務處理類 6

8. 應用 6

9. 疑難雜症 7

  

前言

數據庫的使用在軟件編程中占有很大的一個比例。尤其是在管理系統中,基本上沒有哪個系統能離開數據庫而單獨存在。在編寫數據庫訪問程序時最讓人頭疼的就是拼SQL,一般都需要在數據庫和VS里顛倒好多次才能寫出我們想要的那個語句。ORM的出現很好的解決了這個問題,它可以把SQL相關程序的編寫變成類似強類型的語句,方便編寫和調試,大大提高了工作效率。下面就把我在項目中如何使用EntiryFramework做一下簡單的記錄。開發環境:VS2010,SQLServer208,EntityFramework6

 

1. 建立解決方案項目結構

EntityFramework是用來訪問數據庫的,根工程的類型沒有關系,我們可以把它用用C/S的工程當中,也可以把它用到 B/S的工程當中。為了展示EntityFramework的使用方法,我們首先得建立一個例子解決方案。這個解決方案的最基礎的普通三層結構,因為數據的訪問主要靠EntityFramework來實現,所以數據訪問層的實現基本看不出來了,使得整個解決方案好像就是個兩層的一樣。下面我們通過表格的形式來說明一下這個解決方案中各個工程的類型和做用。

工程名

層次

類型

作用

是否引入EF

JZAPP

展示層

應用程序

應用程序

BLL

業務邏輯層

類庫

邏輯運算,數據訪問

Model

實體類

類庫

數據庫表到類的映射

 

2. 導入EntityFramework類庫

用Nuget把最新版本的EntityFramework導入到BLL,Model兩個項目中。

3. 編寫實體類

下面我們以下面圖中這個實體類做為樣本,來了解一下EntityFramework中的實體類如何定義。實體類是數據庫表的映射,所以這個類的名稱,屬性名稱,屬性類型都是根我們設計的表有關聯了。具體數據庫中的類型映射為C#中的什么類型沒有做過詳細的研究,大概用過的總結如下,如果以后還會用到其他的,還會添加到這里來的。

SqlServer中的類型

C#中的類型

Varchar(N)

string

bit

bool

datetime

DateTime

int

integer

 

數據庫定義如下:

根據表格,我們可以把上面的數據庫表寫為如下實體類,實體類統一放到Model工程里:

using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;

namespace Model
{
    [Table("User")]
    public class UserDefinition
    {
        /// <summary>
        /// 用?戶§id
        /// </summary>
        [Key,DatabaseGenerated(DatabaseGeneratedOption.None)]
        public string UserId { set; get; }
        public string LoginName { set; get; }
        public string Name { set; get; }
        public string Password { set; get; }
        public bool Sex { set; get; }
        public string DeptId { set; get; }
        public DateTime CreateDate { set; get; }
        public int Status { set; get; }
        public string SizeId { get; set; }
        public bool Visible { get; set; }
    }
}
View Code

 

  •  [Table("User")]:定義UserDefinition對應的數據庫表為User
  •  [Key]:定義UserId 為主鍵
  •  [DatabaseGenerated(DatabaseGeneratedOption.None)]:定義字段的數據生成項;DatabaseGeneratedOption有三個值;Identity:自增長;None:不處理;Computed:計算列。

4. 編輯連接字符串

連接字符串放在JZAPP工程的配置文件里(app.config),如果工程中有這個文件那就直接使用,如果沒有就新建一個。

在配置文件里添加一個connectionStrings節。它是configuration的子節點。

 

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <connectionStrings>
    <add name="ABC" 
         connectionString="Data Source=127.0.0.1;Initial Catalog=abc;Persist Security Info=True;User ID=sa;Password=landmark" 
         providerName="System.Data.SqlClient" />
  </connectionStrings>
</configuration>
View Code

 

  •  Name:本連接字符串的名稱,它在本程序中用於BaseBLL類的構造函數中
  •  Data Source:數據庫服務器的名稱,也可以是IP,URL
  •  Initial Catalog:數據庫的名稱貸
  •  User ID:數據庫的用戶名
  •  Password:數據庫密碼

5. 編寫BaseBLL類

這個類是訪問數據庫的基礎,有了這個類才可以寫其他的業務處理。如果沒有業務處理,可以直接用這個類操作數據庫。它必須繼承自DbContext。

using System.Data.Entity;
using Model;
using System.Data.Entity.SqlServer;

namespace BLL
{
    public class BaseBLL:DbContext
    {
        public DbSet<UserDefinition> User { get; set; }

        public BaseBLL()
            : base("abc")
        { 
        
        }
    }
}
View Code

 

編寫這個類要注意三點:

  •  BaseBLL必須繼承自DbContext
  •  用DbSet<>類型實例化每一個實體類
  •  在構造函數中賦值連接字符串的名稱

 

6. 編寫業務處理超類

 

我們可以針對不同的業務來編寫代碼,在程序開發中,遇到重復性太強的地方,把它總結一下,寫出了以下幾個常函數,把它們定義成了一個父類:

 

public class ParentBLL<T> where T : class
        {
            public virtual void Add(T p)
            {
                using (BaseBLL bll = new BaseBLL())
                {
                    bll.Set<T>().Add(p);
                    bll.SaveChanges();
                }
            }

            public T Find(object p)
            {
                using (BaseBLL bll = new BaseBLL())
                {
                    return bll.Set<T>().Find(p);
                }
            }

            public IList<T> Query()
            {
                using (BaseBLL bll = new BaseBLL())
                {
                    return (from o in bll.Set<T>() select o).ToList();
                }
            }

            public virtual void Remove(T p)
            {
                using (BaseBLL bll = new BaseBLL())
                {
                    bll.Set<T>().Attach(p);
                    bll.Set<T>().Remove(p);
                    bll.SaveChanges();
                }
            }

            public virtual void Update(T p)
            {
                using (BaseBLL bll = new BaseBLL())
                {
                    bll.Entry(p).State = EntityState.Modified;
                    bll.SaveChanges();
                }
            }
        }
View Code

 

7. 編寫業務處理類

業務處理類一開始應該是非常簡單的,我們直接用業務處理類的父類來實現它就我們開始的使用了。

 

using Model;
using System.Data.Entity.SqlServer;

namespace BLL
{
    public class UserBLL : ParentBLL<UserDefinition>
    {

    }
}
View Code

8. 建庫SQL

create table "User" (
   UserId               varchar(100)         not null,
   LoginName            varchar(100)         null,
   Name                 varchar(100)         null,
   Password             varchar(100)         null,
   Sex                  bit                  null,
   DeptId               varchar(100)         null,
   CreateDate           datetime             null,
   Status               int                  null,
   SizeId               varchar(100)         not null,
   Visible              bit                  null,
   constraint PK_USER primary key (UserId)
)
Go
View Code

 

9. 應用

下面的程序中用上面的框架寫的一個添加數據程序。

 

        private void button1_Click(object sender, EventArgs e)
        {
            var bll = new UserBLL();
            var p = new UserDefinition();
            p.UserId = Guid.NewGuid().ToString();
            p.Name = Guid.NewGuid().ToString();
            p.SizeId = Guid.NewGuid().ToString();
            p.CreateDate = DateTime.Now;
            bll.Add(p);
        }
View Code

 

 

10. 疑難雜症

 

寫到這里關於EF的應用就算是已經說完了。憑借上面的代碼,我們已經可以用EF來訪問數據庫了。如果這里面還有一人雷。如果把上面的代碼直接復制到工程里去執行可能做引發一個很莫名其妙的錯誤,那就是EF的一個程序集沒有輸出到JZAPP的輸出目錄里面。

EF6在安裝到項目時在項目里添加了兩個程序集分別為EntityFramework和EntityFramework.Sqlserver.我們的解決方案里。Model和BLL工程引用了EntityFramework和EntityFramework.Sqlserver;JZAPP又引用了 Model和BLL。JZAPP沒有直接引用EntityFramework和EntityFramework.Sqlserver。編譯解決方案后,Model和BLL工程的輸出目錄里有EntityFramework和EntityFramework.Sqlserver程序集。JZAPP工程的輸出目錄里只有EntityFramework一個程序集。工程可以編譯通過,但是運行就會出錯誤,這個問題剛開始很讓我莫名其妙。后來經過哥兒們的幫忙看到一個博客。里面有一句話(間接引用程序集,如果只是引用而沒有調用,程序集不會被輸出到目標目錄)讓我知道了原因。經過測試這句話是正確的。解決方法就是在程序中調用一下這個程序集里的程序。如下:

 

using Model;
using System.Data.Entity.SqlServer;

namespace BLL
{
    public class UserBLL : ParentBLL<UserDefinition>
    {
        private string UserName()
        {
            using (var bll = new BaseBLL())
            {
                return SqlFunctions.UserName();
            }
        }
    }
}
View Code

 

 

隨便找一個地方寫一個沒用的函數就可以了。經過測試這個方法編譯可以通過,也能解決上面的問題。但是調用會出錯。沒關系了,解決問題就好了。SqlFunctions類具體怎么用以后再研究吧。

好像還有其他更好的方法來解決這個問題,如果你知道,請告訴我,謝謝。

 

 


免責聲明!

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



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