我正處於建立新開發項目的早期階段,我不確定如何設置我的數據庫訪問策略。我將使用Visual Studio 2012,並將以.NET 4.5和SQL Server 2008或2012爲目標。實體框架,Dapper和SSDT的組合?
我不確定是否使用實體框架,如果是,使用實體框架。由於從數據庫中讀取數據然後處理它將成爲此應用程序的主要工作,查詢性能將變得非常重要。我知道EF5在這方面比EF4.x好很多,但這並不是我最擔心的固有的EF開銷(儘管Dapper至少有兩倍的速度),但更多的是它爲你提供的懶惰作爲開發人員,因爲通過LINQ查詢太多太容易了。所以我希望純SQL查詢成爲獲取數據的主要方式。
不過,我會最懷念EF是:
- 編譯時查詢檢查。
- 更改跟蹤。
- 第一次開發代碼。
- 工作模式的單位。
我可以在沒有變更追蹤的情況下生活,通常不難確定新增或更新的內容。
我所希望的是,這個項目的開發人員不必亂用表格設計師,但他們可以簡單地編寫POCO。所以爲此,我非常欣賞EF的代碼優先方法。有了這個,開發人員可以克隆源代碼,請致電update-database
並擁有一個可工作的本地數據庫。這在過去對我來說非常合適。
另一件對我來說非常重要的事情是一個工作模式單元,或插入和更新的原子性。我想排隊所有更改,並有一個點,我撥打SaveChanges
。使用像DapperExtensions
這樣的庫,您會得到一個Insert
方法,但它會立即執行數據庫調用。你可以通過在它周圍包裝一個事務來使它成爲原子,但這與排隊它不一樣。所以我必須爲此自行推出某種排隊機制。
對於編譯時查詢檢查,我考慮使用SQL Server數據工具(SSDT)。查詢將是存儲過程(以避免C#代碼中的大型查詢字符串blob)以及使用SSDT,這些可以在構建時檢查。 SSDT的另一個優點是可以將存儲過程從Visual Studio部署到目標數據庫。最重要的是,這些SQL腳本將存在於源代碼管理中。
因此,既然,我的解決方案將基本上由三個數據訪問技術:
實體框架
- 將負責創建從POCO datamodels數據庫。
- 將用於通過其工作模式插入/更新數據。需要注意的是,您首先必須將通過SQL獲取的實體
Attach
添加到上下文中。
SSDT
- 將用於在編譯時間來驗證SQL腳本。
- 允許腳本存在於Git中。
- 將部署EF無法部署到您的數據庫的東西。
小巧玲瓏/其他微型ORM
- 將用於獲取數據
我不禁覺得這是一個有點怪人解決方案,我用各種的一切的零碎。我還不確定SSDT和EF會以一種很好的方式一起工作。這個快速的例子似乎工作正常,但:
// Combo of Dapper, EF and a stored proc that was published through SSDT
static void Main(string[] args)
{
var connectionString = ConfigurationManager
.ConnectionStrings["DbDataContext"].ConnectionString;
using (var conn = new SqlConnection(connectionString))
using (var ctx = new DbDataContext())
{
conn.Open();
var product = conn.Query<Product>("GetProduct",
commandType: CommandType.StoredProcedure).First();
ctx.Products.Attach(product);
var order = new Order
{
Product = product
};
ctx.Orders.Add(order);
ctx.SaveChanges();
}
}
這種方法似乎可以工作,但它也很混亂。但是如果我放棄SSDT,我會錯過SQL的編譯時檢查,如果我放棄實體框架,我會錯過代碼優先和更容易的插入,如果我放棄直接SQL,我會錯過大量的表現。
是否有替代品可以忽略?如果不是,這裏最好的辦法是什麼?
「作爲開發者提供的懶惰」 - 這是你的工作,不要懶惰; EF提供完美的性能工程。 – millimoose
是的,但不使用LINQ。你必須下到原始的SQL,然後它仍然只有普通ADO.NET/Dapper(http://goo.gl/ctD9f)的一半。不妨跟Dapper一起去查詢。然而,我想避免在C#代碼中查詢大字符串的匿名blob,這就是爲什麼我查看SSDT將其移出代碼的原因。 – JulianR
好的,但這是開發人員控制之外的框架開銷問題。我的觀點僅僅是「提供懶惰」不是選擇或不選擇技術的好理由。如果您願意爲ORM「深度」交換開銷,您仍然可以選擇避免由N + 1選擇問題導致的性能問題。 (這個問題對性能的影響也很大,在原始SQL中也很容易遇到,而且解決起來更具挑戰性,因爲在SQL中編寫大量的uberqueries比LINQ更困難。) – millimoose