Entity Framework Core 2.0 执行不 return PK 的存储过程

Entity Framework Core 2.0 execute stored procedure that doesn't return a PK

EF Core 2.0 似乎要求执行存储过程的结果具有主键。有没有解决的办法?并非所有存储过程 return 都是唯一可识别的行。谢谢!

不,目前 EF Core 无法做到这一点,但在 roadmap 的未来版本中,虽然可能不适用于 v2.1。在 GitHub 上查看这些问题:

我在做开发的时候也发现了这个。您总是可以直接使用 Row_Number() Over() as [ObjectName]Id 这样简单的东西在 SQL 服务器中虚拟一个自增键 return。这是一个廉价的 hack,但它满足了需要,因为您可以在这个字段上设置 [Key] 装饰,得到 return,并且它将在其他不明显的 return 中是不同的。

declare @Temp table ( val char);

insert into @Temp values ('a'),('b'),('c');

select 
  --this column is arbitrarily made and only exists to satisfy uniqueness.
  --it provides NO functionality to the underlying code being returned.
  ROW_NUMBER() Over(order by val) as TempId
, val 
from @Temp

以及 return 的模型:

public sealed class pTempResult
{
    [Key]
    public int TempId{ get; set; }
    public int Val { get; set; }
}

对于我所做的,我还在我创建的上下文中启用了一个 DbSet 对象:

public virtual DbSet<pTempResult> { get; set; }

然后在我的控制器中我会这样调用它:

await _context.pTempResult.FromSql("pMyProc @p0, @p1, @p2", parameters: new[] { 1, "string" }).ToListAsync();

这样我得到了一个结构良好的对象,但同时直接调用了我需要得到这个结构良好的对象的过程。请记住,在 Entity Framework Core AFAIK 中,您必须添加迁移以创建 proc(如果它尚不存在)。 EG:如果我想从代码中填充数据库中的过程,我需要在迁移的 'up' 部分中手动编写 SQL:

protected override void Up(MigrationBuilder migrationBuilder)
{
   migrationBuilder.Sql(
   "create proc pGetTemp" +
   "( @Id int,  @Text varchar(16) as " +
   "BEGIN " +
   "Select * from Temp " +
   "Where Id = @Id and text = @Text " +
   "END "
   ); 
}

protected override void Down(MigrationBuilder migrationBuilder)
{
   migrationBuilder.Sql("drop proc pGetTemp");
}

同样,这不是很好,也不是最优的,但是如果你想使用带有 Entity Framework Core 的程序,我可以验证它是否有效。