【问题标题】:execute stored procedure in entity Framework Core without expecting map to dbset在实体框架核心中执行存储过程,而不需要映射到 dbset
【发布时间】:2019-01-30 20:58:31
【问题描述】:

我正在研究 .NET CORE,即实体框架核心。我有需要从 .NET 类执行的存储过程。我的存储过程需要一些“上下文”,我不知道如何处理这个问题,尽管我有 dataView 这是最后一个例外。

如果我可以使用我的 dataView 而不是 context.dataModel 类,当前的实现 (Context.Claims.FromSql) ,我会感到很困惑

数据视图

public class ClaimDataView
{
    public Guid ClaimId { get; set; }
    public int IdNum { get; set; }
    public string Value { get; set; }
    public DateTime ExpirationDate { get; set; }
    public ClaimAttributionActions Action { get; set; }
    public bool ActiveStateForRole { get; set; }

}

存储过程调用

public Guid UserId { get; set; }
public Guid ClientId { get; set; }
public Guid ConsultationId { get; set; }

  var userParam = new SqlParameter("@UserVal", UserId);
  var clientParam = new SqlParameter("@ClientVal", ConsultationId);
  var consultationParam = new SqlParameter("@ConsultationVal", ConsultationId);

 //**************need help in following line
  var query = Context.Claims.FromSql("EXECUTE dbo.ListUserClaims @userId=@UserVal, @clientId=@ClientVal, @consultationId=@ConsultationVal"
            , userParam, clientParam, consultationParam);

新的更新

moduleContext 类

  protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
       //other models....
       modelBuilder.Query<ClaimDataView>();
    }

存储过程从

执行
 var query = Context.Query<UserDataView>().FromSql("EXECUTE dbo.ListUserClaims @userId=@UserVal, @clientId=@ClientVal, @consultationId=@ConsultationVal"
            , userParam, clientParam, consultationParam);

错误

System.InvalidOperationException: Cannot create a DbSet for 'UserDataView' because this type is not included in the model for the context.
 at Microsoft.EntityFrameworkCore.Internal.InternalDbQuery`1.get_EntityType()

【问题讨论】:

    标签: c# stored-procedures .net-core entity-framework-core


    【解决方案1】:

    您可以使用 EF Core 2.1 中引入的Query Types

    首先你需要将你的类注册为查询类型:

    modelBuilder.Query<ClaimDataView>();
    

    然后您可以使用Context.Query&lt;ClaimDataView&gt;() 代替您当前的Context.Claims

    var query = Context.Query<ClaimDataView>().FromSql(...);
    

    更新(EF Core 3.x+)

    从EF Core 3.0开始,查询类型一直是consolidated with entity types并重命名为Keyless Entity Types,所以对应的代码是

    modelBuilder.Entity<ClaimDataView>().HasNoKey().ToView(null);
    

    var query = Context.Set<ClaimDataView>().FromSql(...);
    

    【讨论】:

    • 非常感谢您让我朝着正确的方向前进,但是我仍然无处可寻...我已经更新了我的问题...请参阅 newUpate 标题下方的代码...我已在模型类中添加但是尚未为 ClaimDataView 创建任何配置。我不确定我是否需要它,但出现错误...参考上面
    • 它不应该为ClaimDataView 创建DbSet。确保您的上下文中没有DbSet&lt;ClaimDataView,也没有modelBuilder.Entity&lt;ClaimDataView&gt;() 调用。
    • 注意到您更新的代码在某些部分使用UserDataView,而在其他部分使用ClaimDataView。错字?还是新异常的原因?
    • 另请注意,FromSql 已替换为 FromSqlInterpolatedFromSqlRaw
    • @EgorPavlikhin 我想这取决于你想要做什么。在这种情况下避免使用 DbSet 的原因是不要将您的实体映射到表。无键类型将您的类型注册到 EF 模型,而无需在 DB 端为其创建表。然后,您可以在您的类型中使用存储过程。
    【解决方案2】:

    如果您不在 2.1 版上,则需要添加:

    public DbSet<ClaimDataView> ClaimDataView { get; set; }
    

    到你的模块上下文。 并将 NotMapped 添加到您的课程中:

    [NotMapped]
    public class ClaimDataView
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-09-18
      • 1970-01-01
      • 1970-01-01
      • 2011-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多