2014-05-01 33 views
1

我有一個接受tvp作爲參數的sproc。我測試了它,它在db端工作正常。現在在我的C#項目中,我嘗試在edmx中添加該存儲過程並獲得跟隨錯誤。EntityFramework 5.0和TVP不能一起工作

消息8函數「usp_MysprocName」具有在具有其當前不支持針對目標.NET Framework版本數據類型「表型」參數索引0的參數「ParameterNameTVP」。該功能被排除在外。

我將我的.net框架從4.0升級到4.5,並通過nuget重新安裝(因此它可以與新的.net 4.5一起使用)實體框架庫並仍然顯示相同的錯誤。 我發現here entityframework 5.0是支持表值函數(我必須使用5.0版本不是最新的6)。至於.net框架,我正在使用最新的。我不知道爲什麼VS不讓我導入或添加新的sproc。 有什麼建議嗎?

+0

您可以將對象轉換爲一個DataTable使用[CopyToDataTable](http://msdn.microsoft.com/en-us/library/bb396189(v = vs.110).aspx),然後使用SqlCommand調用存儲過程,如[使用帶EF的TVPs]中所示( http://stackoverflow.com/questions/19545835/using-sql-table-valued-parameter-with-entity-framework) –

+0

https:// stackoverflow.com/questions/13601366/entityframework-and-tablevalued-parameter –

回答

1

實體框架不支持帶有TVP的存儲過程。但是,支持表值函數,但它不是一回事。爲了達到類似的結果,我所要做的就是改變參數的數據類型並使用xml。然後我寫了一個TVF來讀取xml並返回一個表加入。

假設你傳遞一個XML這樣的:
<列表> <ID/ID> < /列表>

create function [dbo].[XMLToTable] (@xml xml) 
returns table 
as 
return (
--get the ids from the xml 
select Item.value('.', 'int') as id from @xml.nodes('//id') as T(Item) 
) 

,你的選擇會是這樣

select t.* from MyTable t 
inner join dbo.XMLToTable(@myXmlParam) x on x.id = t.id 

EF會將此視爲一個字符串參數,並且您只需傳遞它即可。這是相對較快的,因爲它使用內聯表值函數。不幸的是,它是EF決定支持TVP之前的一種解決方法。

請在此給予好評的功能要求: http://data.uservoice.com/forums/72025-entity-framework-feature-suggestions/status/317789

編輯: 這裏是你如何處理多個值稍微複雜的例子:

declare @xml xml = 
' 
<complex> 
    <companies> 
     <id>123456</id> 
     <name>My Company</name> 
    </companies> 
    <companies> 
     <id>147889</id> 
     <name>Some Co</name> 
    </companies> 
</complex> 
' 

declare @tbl table (id int, name varchar(50)) 

insert into @tbl values (123456, 'My Company'), 
      (147889, 'Some Co'), 
      (788545, 'Great Corp') 


select * from @tbl co 
left join dbo.XMLCompanies(@xml) x on x.id = co.id 

create function [dbo].[XMLCompanies] (@xml xml) 
returns table 
as 
return (
--get the ids from the xml 
select 
    id=Item.value('./id[1]', 'int') 
    ,name=Item.value('./name[1]', 'varchar(50)') 
from @xml.nodes('//companies') as T(Item) 
) 
+0

如果您需要將對象轉換爲XML字符串,爲什麼不將它們轉換爲DataTable並使用純ADO.NET調用存儲過程? –

+0

這是另一種解決方案,但是您失去了通過數據模型導入和更新您的特效的好處。但是,OP可能會考慮到這一點。 此外,EF提供了一種手動調用procs而不必依賴純ADO.net的方法,但是,您將無法導入proc並自動生成複雜類型。 – Eric

+0

當您必須將實體轉換爲字符串時,您已經失去了導入的映射優勢。您從導入中獲得的唯一其他東西是避免編寫調用該過程所需的5-6行。TVPS的性能優勢比導入的便利性更重要 –