使用了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), 跨異質資料庫的可能性就降低(但跨異質資料庫的需求真的存在嗎?)
- 當某些複雜的sql 需要自行組織SQL來做效能調教時,有兩個選擇
以下為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);