[ORM] Entity Framework(2) CodeFirst進階

來源:互聯網
上載者:User

標籤:

    在上一節中,實現了CodeFirst快速入門。但是很多與資料庫的細節還無法自訂。以及使用EF過程中,需要注意的事項。

    在本節中,會涉及到以下

  • EF中的連接字串
  • EF的對象狀態
  • 消極式載入,為什麼需要Virtual,貪婪載入
  • 繞過EF,直接SQL查詢
  • 查看EF產生SQL語句
  • 實體與資料庫的映射通過DataAnnotation與FluentAPI兩種方式
  • 結合MVC非同步控制器做個CRUD例子
  • 建議

 

連接字串

  1個完整的連接字串  IP:連接埠\執行個體名 資料庫名組成

  Nuget安裝完EF會在*.config的entityFramework節點下添加,表示使用LocalDb資料庫,執行個體名為v11.0。

<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">      <parameters>        <parameter value="v11.0" />      </parameters></defaultConnectionFactory>

  而資料庫名,預設為類的全限定名。如下調用父類建構函式,表示資料庫名為SaleDb。而不是命名空間+類名。

    public class SaleDb : DbContext    {        public SaleDb():base("SaleDb")        {              }    }

  當然,在這個建構函式裡,可以完整的寫上完整的連接字串。

 

EF的對象狀態

  db.Entry(TEntity).State  (附加Entity,並設定狀態)

    public enum EntityState    {        // 摘要:         //     The entity is not being tracked by the context.  An entity is in this state        //     immediately after it has been created with the new operator or with one of        //     the System.Data.Entity.DbSet Create methods.        Detached = 1,        //        // 摘要:         //     The entity is being tracked by the context and exists in the database, and        //     its property values have not changed from the values in the database.        Unchanged = 2,        //        // 摘要:         //     The entity is being tracked by the context but does not yet exist in the        //     database.        Added = 4,        //        // 摘要:         //     The entity is being tracked by the context and exists in the database, but        //     has been marked for deletion from the database the next time SaveChanges        //     is called.        Deleted = 8,        //        // 摘要:         //     The entity is being tracked by the context and exists in the database, and        //     some or all of its property values have been modified.        Modified = 16,    }

  

消極式載入,貪婪載入,為什麼需要Virtual

  消極式載入(lazy load)是(也稱為懶載入),消極式載入機制是為了避免一些無謂的效能開銷而提出來的,所謂消極式載入就是當在真正需要資料的時候,才真正執行資料載入操作。可以簡單理解為,只有在使用的時候,才會發出sql語句進行查詢。

  貪婪載入則是一次性把相關的表也載入進來。

在EF中,預設是支援消極式載入的。

  db.Configuration.LazyLoadingEnabled = false;    //設定禁用消極式載入

如果想單個貪婪載入某個表。則通過Include("表名")

  db.Orders.Include("OrderItems");          //把OrderItems表一併載入進來

 

Virtual關鍵字

通常相關連的表作為Entity屬性的時候,使用Virtual關鍵字修飾符。如果不加Virtual關鍵字,則關聯的類只是一個普通的POCO類型。get,set方法為空白實現。

使用Virtual關鍵字後,EF產生一個代理類來重寫get和set方法。實現需要的功能。

  

繞過EF,直接SQL查詢

  EF作為一個架構,也不可能做到滿足所有需求。EF提供了直接操作Ado.net方式。

有三個 API 支援:

  • DbContext.Database.ExecuteSqlCommand
  • DbContext.Database.SqlQuery
  • DbSet.SqlQuery

         

執行sql 返回受影響函數。

public int ExecuteSqlCommand(string sql, params object[] parameters); 

 

執行sql 返回查詢結果並自動對應到指定類上。(不會被EF跟蹤狀態)

DbRawSqlQuery<TElement> SqlQuery<TElement>(string sql, params object[] parameters);

 

執行sql 返回查詢結果並自動對應到指定類上。(被EF跟蹤狀態。DbSqlQuery繼承自DbRawSqlQuery)

virtual DbSqlQuery<TEntity> SqlQuery(string sql, params object[] parameters);

 

查看EF產生SQL語句

  當使用EF執行一個複雜的查詢時候。我們需要知道EF是否按照我們所需執行。這時,就需要查看EF產生的語句。

  1. 執行IQueryable<T>.ToString(); 即可查看產生的sql語句。
  2. 通過EFProviderWrappers,這裡不做贅述。

 

DataAnnotation

  DataAnnotation 特性由.NET 3.5中引進,給.NET中的類提供了一種添加驗證的方式。同時在EF中,也是添加約束與個人化一種方式。

常用到以下特性。

  1. KeyAttribute:對應資料庫中的主鍵
  2. RequiredAttribute:對應資料庫中欄位的資料是否可以為null
  3. MaxLengthAttribute:對應資料庫中字串類型欄位的最大長度
  4. MinLengthAttribute:在資料庫中無對應,但在代碼中字串最小長度
  5. TimestampAttribute:將列的資料類型指定為行版本
  6. DatabaseGeneratedAttribute:標記指定實體屬性是由資料庫產生的,並指定建置原則(None資料庫不產生值,Identity當插入行時,資料庫產生值,Computed當插入或更新行時,資料庫產生值)
  7. ColumnAttribute:指定實體屬性在資料庫中的列名及資料類型
  8. TableAttribute:指定實體類對應的資料表名
  9. ForeignKeyAttribute:指定導覽屬性的外鍵欄位
  10. NotMappedAttribute:標記指定實體屬性在建立資料庫中不建立對應欄位
  11. ConcurrencyCheck:並發標記
    public class Order    {        [Key]        public int Id { get; set; }        [StringLength(200)]        public string Name { get; set; }        public int UserId { get; set; }        [ForeignKey("UserId")]        public User User { get; set; }        public virtual ICollection<OrderItem> OrderItems { get; set; }    }

  

 

FluentAPI

  使用DataAnnotation(DA)非常方便,但有時我們的POCO類不希望受到EF的直接關聯。或者DA不能滿足需求。這時,我們可以使用FluentAPI方式。

  1. HasKey - KeyAttribute:配置此實體類型的主鍵屬性
  2. IsRequired - RequiredAttribute:將此屬性配置為必需屬性。用於儲存此屬性的資料庫列將不可以為null
  3. HasMaxLength - MaxLengthAttribute:將屬性配置為具有指定的最大長度
  4. IsConcurrencyToken - ConcurrencyCheckAttribute:將屬性配置為用作開放式並發標記
  5. IsRowVersion - TimestampAttribute:將屬性配置為資料庫中的行版本。實際資料類型將因使用的資料庫提供者而異。將屬性設定為行版本會自動將屬性配置為開放式並發標記。
        protected override void OnModelCreating(DbModelBuilder modelBuilder)        {            modelBuilder.Entity<AppInfo>().Property(o => o.Id).HasColumnName("AppId");        }

  

MVC非同步控制器做個CRUD例子

  微軟自家的東西關聯總是那麼方便。

在MVC5中,添加控制器的時候選擇使用EF即自動產生這一切。

 

 

建議

  1.模型改變重建資料庫,導致表資料丟失。

    在使用CodeFirst中,當模型改變的時候,採用第一節中的Nuget中EF Migration API方式則不會清空資料。

  2.是否使用預存程序,視圖這些資料庫技術。

    當使用EF 這種ORM架構的時候,就應該輕資料庫技術,重商務邏輯層。我的建議是萬不得已不要使用預存程序,視圖實際只是儲存了SQL語句。

 

MVC5代碼下載:MVCTest

[ORM] Entity Framework(2) CodeFirst進階

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.