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

时间:2018-02-14 15:17:16

标签: entity-framework stored-procedures primary-key .net-core-2.0

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

2 个答案:

答案 0 :(得分:0)

目前,EF Core目前无法实现这一目标,但未来版本的roadmap可能会出现这种情况,但可能不适用于v2.1。在GitHub上看到这些问题:

答案 1 :(得分:0)

我在开发时也发现了这一点。您总是可以使用Row_Number()Over()作为[ObjectName] Id这样简单的东西直接在SQL Server中伪造自增量键返回。这是一个廉价的黑客,但它满足了需要,因为你可以设置你的POCO与[Key]的装饰在这个领域得到回报,它将是一个不同的非独特的回报。

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

返回的模型:

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:如果我想从代码中填充数据库中的过程,我需要在迁移的“向上”部分手动编写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");
}

同样,这不是很漂亮而且不是最佳的,但如果你想使用带有实体框架核心的程序,我可以验证这是否有效。