如何使用 FromSqlRaw Entity Framework Core 3.1 从存储过程中返回多个 SELECT 集
Posted
技术标签:
【中文标题】如何使用 FromSqlRaw Entity Framework Core 3.1 从存储过程中返回多个 SELECT 集【英文标题】:How to return multiple SELECT sets from a stored procedure using FromSqlRaw Entity Framework Core 3.1 【发布时间】:2021-09-10 04:43:17 【问题描述】:我目前在从数据库返回值时遇到问题,我正在使用 SQL Server 存储过程和 ASP.NET Core 3.1 来检索多个 SELECT 集。
这是我的存储过程:
ALTER PROCEDURE [dbo].[MyProc]
@BusinessModelID int
AS
BEGIN
SELECT Id, Title
FROM [dbo].[Channels]
WHERE BusinessModelId = @BusinessModelID;
SELECT Id, Title
FROM [dbo].[Problems]
WHERE BusinessModelId = @BusinessModelID;
SELECT Id, Title
FROM [dbo].[CostStructures]
WHERE BusinessModelId = @BusinessModelID;
SELECT Id, Title
FROM [dbo].[CustomerSegments]
WHERE BusinessModelId = @BusinessModelID;
SELECT Id, Title
FROM [dbo].[KeyMetrics]
WHERE BusinessModelId = @BusinessModelID;
SELECT Id, Title
FROM [dbo].[RevenueStreams]
WHERE BusinessModelId = @BusinessModelID;
SELECT Id, Title
FROM [dbo].[Solutions]
WHERE BusinessModelId = @BusinessModelID;
SELECT Id, Title
FROM [dbo].[Unfairs]
WHERE BusinessModelId = @BusinessModelID;
SELECT Id, Title
FROM [dbo].[Values]
WHERE BusinessModelId = @BusinessModelID;
END
这是我的 C# 代码:
var modelList = _dataContext.Set<BusinessToGet>()
.FromSqlRaw($"EXECUTE MyProc @BusinessModelID=businessModelId")
.ToList();
问题是它应该返回多个集合,但它只返回一个通道。我做错了什么?
提前致谢。
【问题讨论】:
【参考方案1】:更新
在这种情况下,表之间存在重复的主键。尽管下面的 SQL 在 SQL-server 中运行良好,但 EF Core 返回了许多重复实例,因为当 EF Core 看到 Id = 1 的实例时,它会将其用于 Id = 1 的所有后续实例。
解决方法是使用无密钥 DTO 进行 FromSqlRaw
查询。
[Keyless]
public class BlogPostsCount
Id,
public int Id get; set;
public string Title get; set;
https://docs.microsoft.com/en-us/ef/core/modeling/keyless-entity-types?tabs=data-annotations
使用 UNION 应该可以解决这个问题。如果表之间的数据类型不同,您可能还需要转换列值以产生统一的结果。如果您有跨表重复,并且需要全部,请使用 UNION ALL。
SELECT Id, Title FROM [dbo].[Channels] WHERE BusinessModelId = @BusinessModelID
UNION
SELECT Id,Title FROM [dbo].[Problems] WHERE BusinessModelId = @BusinessModelID
UNION
SELECT Id, Title FROM [dbo].[CostStructures] WHERE BusinessModelId = @BusinessModelID
UNION
SELECT Id, Title FROM [dbo].[CustomerSegments] WHERE BusinessModelId = @BusinessModelID
UNION
SELECT Id, Title FROM [dbo].[KeyMetrics] WHERE BusinessModelId = @BusinessModelID
UNION
SELECT Id, Title FROM [dbo].[RevenueStreams] WHERE BusinessModelId = @BusinessModelID
UNION
SELECT Id, Title FROM [dbo].[Solutions] WHERE BusinessModelId = @BusinessModelID
UNION
SELECT Id, Title FROM [dbo].[Unfairs] WHERE BusinessModelId = @BusinessModelID
UNION
SELECT Id, Title FROM [dbo].[Values] WHERE BusinessModelId = @BusinessModelID
【讨论】:
我尝试使用 UNION ALL,但它似乎仍然返回重复项,它返回正确的行数,但在到达 C# 代码时返回正确的数据。 :( @RodolfoA.Calvo:UNION ALL 将返回重复项(如果有)。 UNION 执行隐式select distinct
。您能否更具体地说明您遇到的问题? BR
当然!您的解决方案在 SQL Server 中完美运行,但是现在当我调试我的 C# 代码时,数据只带有一个重复的结果,但数字正确,例如:在 SQL 中,结果是 1 - 我的频道 1 - 我的问题 1-成本结构......等等,这是正确的,但在 C# 中,结果是 1 - 我的频道 1 - 我的频道 1 - 我的频道 1 - 我的频道 1 - 我的频道。我在 SQL SP SELECT DISTINCT * FROM [dbo].[Channels] WHERE BusinessModelId = @BusinessModelID UNION ALL 中为所有这些人做了这个
我认为您也必须添加 TableName 属性才能知道谁是谁。并添加到每个选择查询“'Chanels' as a TableName”例如
@Serge:我正在研究这个似乎没有任何注释的相关问题:github.com/dotnet/efcore/issues/24078BR以上是关于如何使用 FromSqlRaw Entity Framework Core 3.1 从存储过程中返回多个 SELECT 集的主要内容,如果未能解决你的问题,请参考以下文章
如何在 EF.core 中使用 FromSqlRaw 指定列
如何在 c# 实体框架核心中使用 FromSqlRaw() 将 OUTPUT 参数发送到 MySql 存储过程
如何通过 FromSqlRaw 在 EF Core 3.0 中调用存储过程
解决org.hibernate.HibernateException: identifier of an instance of com.ahd.entity.Order was altered fr