【发布时间】:2018-04-15 11:35:06
【问题描述】:
EF Core 支持执行存储过程并将结果映射到实体(现有实体或专门为存储过程创建的实体)。
我已经阅读了很多关于这个主题的问题,例如https://github.com/aspnet/EntityFrameworkCore/issues/1862https://github.com/aspnet/EntityFrameworkCore/issues/245。
我认为#1862 将启用对只执行SELECT 操作的存储过程的服务器评估。
但是,我的代码似乎导致对数据库的 2 次调用。有没有办法通过一次调用数据库来执行以下代码?
var customIdsQuery = _dbContext.Set<CustomId>()
.FromSql($"dbo.GetCustomIDs {username}").AsNoTracking();
var eventsQuery = _dbContext.Event.Where(ev => ev.User.Username == username)
.Join(customIdsQuery, ev => rev.CustomId, cid=> cid.Id, (ev, cid) => ev).AsNoTracking();
var events = eventsQuery.ToList(); // 2 database calls
模型构建器看起来像这样:
modelBuilder.Entity<CustomId>(); // For the stored procedure
modelBuilder.Entity<Event>(entity => // Key is defined as attribute on the model
{
entity.HasOne(d => d.Meeting)
.WithMany(p => p.Event)
.HasForeignKey(d => d.MeetingId);
entity.HasOne(d => d.User)
.WithMany(p => p.Event)
.HasForeignKey(d => d.UserId);
});
为了能够在 SQL 服务器上评估整个查询,我是否遗漏了一些明显的东西?来自文档(https://docs.microsoft.com/en-us/ef/core/querying/raw-sql):
传递给此方法的 SELECT 语句通常应该是可组合的:如果 EF Core 需要评估服务器上的其他查询运算符(例如,转换在 FromSql 之后应用的 LINQ 运算符),则提供的 SQL 将被视为子查询
我的存储过程实际上就像一个SELECT 语句,有没有办法强制它被识别为这样?
谢谢。
【问题讨论】:
-
发布
GetCustomIDs代码 -
您缺少文档链接中 Limitations 部分的最后一段:“除 SELECT 之外的 SQL 语句被自动识别为不可组合。因此,存储过程的完整结果始终返回给客户端,并且在 FromSql 之后应用的任何 LINQ 运算符都会在内存中进行评估。” 因此,即使您的 SP 类似于
SELECT,它们也不会被视为此类。这是有道理的,因为 EFC 无法知道您的 SP 中的内容。
标签: c# sql-server entity-framework entity-framework-core