我在导入存储过程时遇到了权限框架6.0.0.0的问题,无论我做什么都不返回结果集,而是只返回整数或设置为none。 下面是sp。
alter proc spGetProd
@Prod nvarchar(500)
as
begin
SET FMTONLY OFF
IF OBJECT_ID('tempdb..##PRODUCTTABLE') IS NOT NULL DROP TABLE ##PRODUCTTABLE
DECLARE @MYQUERY nvarchar(MAX), @my_Div nvarchar(500);
set @my_Div = REPLACE(@Prod, ',', ''',''');
SET @MYQUERY = 'SELECT DISTINCT [GNo],[GName]
into ##PRODUCTTABLE FROM ABC
where Div IN ('''+@my_Div+''')
order by GNo'
EXEC (@MYQUERY)
SELECT GNo, GName FROM ##PRODUCTTABLE;
drop table ##PRODUCTTABLE;
end
无论我做什么,无论我设置SET FMTONLY OFF / ON
,都行不通。我做了很久以后它只工作了一次,当我设置SET FMTONLY OFF
然后删除它并且它适用于那个sp但是对于其他存储过程它不起作用。即使我从select * from ##PRODUCTTABLE;
获取结果集或指定上面的列。
这是我在MVC中的行动。
public JsonResult GetData()
{
var allProducts = gentity.spGetProd("AB"); //return type shows as int.
return Json(allProducts, JsonRequestBehavior.AllowGet);
}
是否还有其他解决方法,因为我的应用程序主要依赖于存储过程,这些存储过程通常会从上面的临时表中返回数据。
答案 0 :(得分:1)
EF无法从存储过程派生结果集的结构,因为它是动态组合的。但是你可以解决这个问题,同时简化存储过程。
首先,创建一个Split
函数,例如this one。然后在存储过程中使用它:
...
BEGIN
SELECT DISTINCT [GNo],[GName]
FROM ABC
JOIN dbo.Split(@Prod) AS prod ON prod.Name = ABC.Div
order by GNo
END
现在EF可以从SELECT
语句中推断出返回的列。
答案 1 :(得分:1)
问题出在您的存储过程中。你的问题很简单,而且你把这些东西弄得很复杂。
只需在数据库中创建此功能。
CREATE FUNCTION dbo.SplitStrings
(
@List NVARCHAR(MAX),
@Delimiter NVARCHAR(255)
)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
(
SELECT Item = y.i.value('(./text())[1]', 'nvarchar(4000)')
FROM
(
SELECT x = CONVERT(XML, '<i>'
+ REPLACE(@List, @Delimiter, '</i><i>')
+ '</i>').query('.')
) AS a CROSS APPLY x.nodes('i') AS y(i)
);
GO
现在您的存储过程看起来像
ALTER PROC spGetProd
@Prod nvarchar(500)
AS
BEGIN
SET NOCOUNT ON;
SELECT DISTINCT [GNo],[GName]
FROM ABC
WHERE Div IN (SELECT Item FROM dbo.SplitStrings(@Prod,','))
ORDER BY GNo;
END
没有临时表,没有额外的变量,没有EXEC,没有对象掉线。只是一个明确的EF选择声明。
答案 2 :(得分:0)
目前尚不清楚如何实际执行程序(动态或使用某种映射)。如果我没记错的话,我在SQL Server 2012中遇到了与结果集结构(模式)相关的一些问题,我不得不使用WITH RESULT SETS来明确告诉预期的结果集结构。
在实体框架中,这可以通过以下方式实现:
var query = "EXECUTE spGetProd @Prod WITH RESULT SETS ((GNo INT, GName NVARCHAR(1024)))";
var result = context.Database.SqlQuery<EntityType>(sql).ToList();
反馈后修改
如果结果集结构是动态的,我不认为实体框架在这里是合适的。相反,请获取results into a DataSet。
如果已知最大结构,则可以将DataSet信息传输到对象列表中:
public static DataTable ConvertTo<T>(IList<T> list)
{
DataTable table = CreateTable<T>();
Type entityType = typeof(T);
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(entityType);
foreach (T item in list)
{
DataRow row = table.NewRow();
foreach (PropertyDescriptor prop in properties)
{
row[prop.Name] = prop.GetValue(item);
}
table.Rows.Add(row);
}
return table;
}