C# EntityFramework 5.0和TVP不一起工作

C# EntityFramework 5.0和TVP不一起工作,c#,.net,sql-server,entity-framework,C#,.net,Sql Server,Entity Framework,我有一个存储过程,它接受tvp作为参数。我测试了它,它在db端工作得很好。现在在我的c项目中,我尝试在edmx中添加该存储过程,并得到以下错误 消息8函数“usp_MysprocName”在参数索引0处有一个参数“ParameterNameTVP”,该参数的数据类型为“table type”,目标.NET Framework版本当前不支持该类型。该功能被排除在外 我将.net framework从4.0升级到4.5并重新安装,因此它可以通过nuget与新的.net 4.5实体框架库一起工作,但仍

我有一个存储过程,它接受tvp作为参数。我测试了它,它在db端工作得很好。现在在我的c项目中,我尝试在edmx中添加该存储过程,并得到以下错误

消息8函数“usp_MysprocName”在参数索引0处有一个参数“ParameterNameTVP”,该参数的数据类型为“table type”,目标.NET Framework版本当前不支持该类型。该功能被排除在外

我将.net framework从4.0升级到4.5并重新安装,因此它可以通过nuget与新的.net 4.5实体框架库一起工作,但仍然显示相同的错误。 我发现entityframework 5.0支持表值函数,我必须使用5.0版本,而不是最新的6。就.net框架而言,我使用的是最新的。我不知道为什么VS不允许我导入或添加新存储过程。
有什么想法吗?

实体框架不支持带有TVP的存储过程。但是,支持表值函数,但它不是同一件事。为了获得类似的结果,我必须做的是更改参数的数据类型并使用xml。然后,我编写了一个TVF来读取xml,并返回一个要连接的表

假设您传递一个xml,如: 1.

您的选择将类似于

select t.* from MyTable t
inner join dbo.XMLToTable(@myXmlParam) x on x.id = t.id
EF将把它当作一个字符串参数,您只需传递它。这相对较快,因为它使用内联表值函数。不幸的是,在EF决定支持TVP之前,这是一个解决办法

请在此处上传功能请求:

编辑: 下面是一个略为复杂的示例,说明如何处理多个值:

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)
)

如果您需要将对象转换为XML字符串,为什么不将它们转换为DataTable,然后使用普通的ADO.NET调用存储过程呢?这是另一种解决方案,但是您失去了通过datamodel导入和更新过程的好处。然而,OP可能会考虑到这一点。此外,EF确实提供了一种手动调用proc的方法,而无需依赖纯ADO.net,但同样,您将无法导入proc并自动生成复杂类型。当您必须将实体转换为字符串时,您已经失去了导入的映射优势。导入的另一个好处是避免编写调用过程所需的5-6行代码。TVP的性能优势比进口的便利性更重要是的,两者都有成本。TVPs的改进意味着可维护性降低,但正如我所注意到的,xml只会略微降低性能。这取决于老年退休金计划的需要。如果他能使用手动呼叫,他将能够实现最终目标,即使用TVPs。但是,如果他需要导入proc,那么没有解决方法是不行的。您可以使用将对象转换为DataTable,然后使用SqlCommand调用存储过程,如中所示
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)
)