Create Proc usp_SelectSomething
@Column1 int,
@Column2 varchar(255)
As
Select * From Table
Where Column1 = @Column1 AND Column2 = @Column2
Go
這樣的話在C# EF 取就會是public ObjectResult但是這樣就沒辦法應對 WHERE col IN(...) 的應用,因為無法動態產生不定數量的參數。sp_SelectSomething(global::System.Int32 column1, global::System.String column2) { ... } _MyDbEntitie.usp_SelectSomething(column1, column2);
最簡單的方法是用這篇裡面寫到的作弊方法,這樣
ALTER PROCEDURE [dbo].[usp_CheatedSelectProductByIds]
@productIds nvarchar(max)
AS
BEGIN
SET NOCOUNT ON
DECLARE @cmd nvarchar(max)
SET @cmd = N'SELECT * FROM Product WHERE id IN (' + @productIds + ')'
EXEC sp_executesql @cmd
END
string cmdStr = "usp_CheatedSelectProductByIds @productIds";
MyLabEntities entities = new MyLabEntities();
var products = entities.Database.SqlQuery<Product>(
cmdStr, new SqlParameter("productIds", input)).ToList();
但是如果你想用var products2 = entities.usp_CheatedSelectProductByIds(input).ToList();這樣的方式,就必須先參考這篇,設定回傳集合為複雜型別,而且因為是用 sp_executesql 去串字串 cmd,EF 不會幫你把複雜型別建出來,你要自己先去手動建出來才有得選,參考
ALTER PROC [dbo].[usp_SelectProductByIds]
@productIds varchar(max)
As
SELECT * FROM Product
WHERE id IN (@productIds)
EF 就會自己幫你把複雜型別建出來;但同時你也會發現不管是entities.Database.SqlQuery所以比較妥當的方法是用你傳入的 CSV 規格字串做一個 temp table,然後以那個 temp table 做子查詢給你的 WHERE IN,參考。
CREATE PROC [dbo].[usp_StableSelectProductByIds]
@productIds nvarchar(max)
As
DECLARE @Delimeter char(1)
SET @Delimeter = ','
DECLARE @tmpTable TABLE(Id nvarchar(50))
DECLARE @Id nvarchar(50)
DECLARE @StartPos int, @Length int
WHILE LEN(@productIds) > 0
BEGIN
SET @StartPos = CHARINDEX(@Delimeter, @productIds)
IF @StartPos < 0 SET @StartPos = 0
SET @Length = LEN(@productIds) - @StartPos - 1
IF @Length < 0 SET @Length = 0
IF @StartPos > 0
BEGIN
SET @Id = SUBSTRING(@productIds, 1, @StartPos - 1)
SET @productIds = SUBSTRING(@productIds, @StartPos + 1, LEN(@productIds) - @StartPos)
END
ELSE
BEGIN
SET @Id = @productIds
SET @productIds = ''
END
INSERT @tmpTable (Id) VALUES(@Id)
END
SELECT * FROM Product
WHERE id IN (SELECT Id FROM @tmpTable)


沒有留言:
張貼留言