[EntityFramework] EF與其Raw SQL Query(使用自訂SQL)使用時機

使用了Entity Framwork 需要多考慮效能的問題,其實大多數的簡單查詢交給Enitity Framework是沒問題的
也加快了 開發的速度,所以懂得利用EF的長處,避開它的缺點 是本文要探討的問題

 

  • EF的使用策略
    • 簡單的DB物件使用EF自動幫你產生的Entity物件存取
    • 複雜且需要手工打造的SQL 交給Store Procedure or Raw SQL Query
    • Entity的自訂屬性(MetadataType)另外定義Class, 也獨立於EF自動產生物件之外,這樣才不會有被覆蓋的問題
       
      
      
      [MetadataType(typeof(CustomerValidation))] 
      public partial class Customer
      {
      
      } 
      
      public class CustomerValidation
      { 
          [Required] 
          public string CustomerID{ get; set; } 
      }
      
      
      

       
  • Raw SQL Query(使用自訂SQL)使用時機
    • 當某些複雜的sql 需要自行組織SQL來做效能調教時,有兩個選擇
      使用store procedure
      這種方式跟EF 的精靈產生實體Table or View類似,只是對應store procedure產生的是 Complex Type
    • 使用自訂SQL(Raw SQL Query)
      優點:靈活使用db hint or join syntax 
      缺點:將會綁定db 的語法(e.g SQL Server), 跨異質資料庫的可能性就降低(但跨異質資料庫的需求真的存在嗎?)

以下為CRUD 範例

簡單的Select 

using (var ctx = new SchoolDBEntities())
{
    var studentList = ctx.Students.SqlQuery("Select * from Student").ToList<Student>();
  
}
     

以上傳進sql後,加入ToList<T>();
T可定義為你想要回傳的物件類別
這樣將可取得強行別的物件

Select + 使用參數

using (var context = new BloggingContext()) 
{ 
    var blogId = 1; 
 
    var blogs = context.Blogs.SqlQuery("dbo.GetBlogById @p0", blogId).Single(); 
}



Update/Delete 
 

using (var ctx = new SchoolDBEntities())
{

    //Update command
    int noOfRowUpdated = ctx.Database.ExecuteSqlCommand("Update student 
            set studentname ='changed student by command' where studentid=1");
    //Insert command
    int noOfRowInserted = ctx.Database.ExecuteSqlCommand("insert into student(studentname) 
            values('New Student')");
    //Delete command
    int noOfRowDeleted = ctx.Database.ExecuteSqlCommand("delete from student 
            where studentid=1");

}
        


Update/Delete + 使用參數 

string sql = "Insert into Customer(CustomerID,CustomerName) 
              VALUES(@customerID,@customerName)";
List<SqlParameter> parameterList = new List<SqlParameter>();
parameterList.Add(new SqlParameter("@customerID","A01"));
parameterList.Add(new SqlParameter("@customerName","Mike"));
SqlParameter[] parameters = parameterList.ToArray();
int result = db.Database.ExecuteSqlCommand(sql, parameters);