2011-07-09 56 views
6

我想知道是否有一個很好的ORM可以自動完成我現在要做的一些手動工作。我們的應用程序大量使用存儲過程,這意味着與數據庫的任何交互都通過存儲過程。ORM可與ASP.NET 4和SQL Server中的存儲過程配合使用

現在,我必須以傳統的方式調用存儲過程,而且非常繁瑣。有沒有做得很好,在處理存儲過程的ORM:

  1. 有輸入/輸出參數是結構化的,這意味着表值類型
  2. 輕鬆允許輸出參數是用戶定義類型,標量和表值
  3. 返回多個記錄集
+0

可能出現[使用存儲過程時ORM最好]的副本(http://stackoverflow.com/questions/687762/which-orm-is-the-best-when-using-stored-procedures) – jgauffin

+0

@ jgauffin:我認爲這個問題在2年後有效。想想2009年3月以來的所有新東西 – gbn

+0

這不是重複的。我試圖找出一個orm或者adapter是否可以對錶值進/出參數做一個適當的工作,同時做很多ado.net的工作。 – Candide

回答

8

Dapper具有相當廣泛的存儲過程支持。

的瑣碎:

create proc spGetOrder 
    @Id int 
as 
select * from Orders where Id = @Id 
select * from OrderItems where OrderId = @Id 

它可以用下面的映射。

var grid = cnn.QueryMultiple("spGetOrder", new {Id = 1}, commandType: CommandType.StoredProcedure); 
var order = grid.Read<Order>(); 
order.Items = grid.Read<OrderItems>(); 

此外,您有支持的:

  1. 多映射器,讓您單排多個對象
  2. 輸入,輸出和返回參數支持
  3. 一個可擴展的接口,用於特定的數據庫參數處理(如TVPs)

舉例來說:

create proc spGetOrderFancy 
    @Id int, 
    @Message nvarchar(100) output 
as 
set @Message = N'My message' 
select * from Orders join Users u on OwnerId = u.Id where Id = @Id 
select * from OrderItems where OrderId = @Id 
return @@rowcount 

能以映射:

var p = new DynamicParameters(); 
p.Add("Id", 1); 
p.Add("Message",direction: ParameterDirection.Output); 
p.Add("rval",direction: ParameterDirection.ReturnValue); 
var grid = cnn.QueryMultiple("spGetOrder", p, commandType: CommandType.StoredProcedure); 
var order = grid.Read<Order,User,Order>((o,u) => {o.Owner = u; return o;}); 
order.Items = grid.Read<OrderItems>(); 

var returnVal = p.Get<int>("rval"); 
var message = p.Get<string>("message"); 

最後,小巧玲瓏還允許自定義參數實現:

public interface IDynamicParameters 
{ 
    void AddParameters(IDbCommand command); 
} 

當實現了這個接口,你可以告訴小巧玲瓏什麼參數你想添加到你的命令。這使您可以支持表值參數和其他數據庫特定功能。

You're using it now on Stack Overflow ...

+3

我花了相當多的時間學習如何使用Dapper,並且看到它在行動中令人印象深刻。我發現表值參數不容易處理,因爲tvps是特定於sql server的,而Dapper試圖保持通用。在測試中有一個示例顯示了IntDynamicParam,但是這只是一個參數,當我確實想保持添加其他參數的能力時。所以,沒有一個快速的解決方案,並且特定於SQL Server的適配器將需要相當多的工作。 – Candide

+0

@Roland tvps有一個非常奇怪的API。把它包裝在一個整潔的幫手中並不容易,如果你傳遞一個IEnumerable 那就需要一種檢測類型名稱的方法。我會看看如果我可以延長測試你可以提高一張票,所以我可以跟蹤 –

+1

@gbn ...看我的編輯...添加了一堆細節 –

1

如果沒記錯,LINQ to SQL具有映射的方法來存儲過程的能力。在Visual Studio中創建LINQ  至  SQL上下文時,可以連接數據庫並將表拖放到設計視圖中。它將檢測任何存儲過程並在模型對象內部生成必要的方法。

請參閱Scott Guthrie的博文LINQ to SQL (Part 6 - Retrieving Data Using Stored Procedures)

+0

嘗試了它,發現它不適用於用戶定義的類型,特別是表類型。 – Candide

+0

該博客文章的末尾提到了對用戶定義類型的支持 –

+0

也許我錯過了一些東西,但我認爲它是指用戶定義的函數。此外,如果定義的類型相當簡單(相當於typedef),但它不適用於更復雜的類型,它就可以工作。 Sql Server中用戶定義的表類型不適用於linq2sql,我讀了幾篇聲明這一點的帖子。不過,謝謝你的回覆。 – Candide

2

查看Entity Framework

+0

EF是相當不錯的,除了表格用戶定義的類型外,它幾乎可以滿足我所需要的一切。 linq2sql也是一樣的缺點。 – Candide

+0

另一方面,只有EF4允許你指定存儲過程來插入,更新,刪除實體。此外,EF4允許您在映射文件中輕鬆創建新的「複雜類型」,以存儲與現有實體(或實體集合)不匹配的proc結果 –

+0

@marc_s,但在某些方面,您的ORM的限制是定義你可以遵循的TSQL編碼風格。削減對TVP的支持可能會使批次的插入複雜化,特別是如果您想要複雜的重複處理。 –