【问题标题】:Entity Framework Core get data from stored procedure and then convert into view model without DbSetEntity Framework Core 从存储过程中获取数据,然后在没有 DbSet 的情况下转换为视图模型
【发布时间】:2020-11-23 23:57:37
【问题描述】:

我在存储库中有一个函数GetForms,该函数的目的是调用存储过程并返回带有数据的行。到目前为止一切正常。

功能

public IEnumerable<FormBO> GetForms() 
{
      var id = "1"
      var Query= _context.FormBO.FromSqlRaw("dbo.SP_Core  @pin_ID={0}", id)
                                .AsNoTracking().ToList(); //3K line of sp
      return Query;
}

型号

public class FormBO
{
    [Key]
    public int? ID { get; set; }
    public int? secondid { get; set; }
    ......
}

DbContext

添加了这段代码,所以上下文认为它是数据库中的一个表,我不需要做更多的事情

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

问题

每当我们搭建数据库和数据库上下文时,它都会重新生成所有文件和代码,因此它会删除

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

我们必须手动添加这一行,有什么办法可以改变逻辑,所以我不必每次 dba 更新数据库时都将这段代码 (DBset&lt;FormBO&gt;) 添加到 DbContext...

我发现了什么

我发现如果我将模型更改为“.Database”并将FromSqlRaw 更改为ExecuteSqlRaw,但它只是将计数返回为 int 而不是行列表。

public IEnumerable<FormBO> GetForms() 
{
    var id = "1"
    var Query = _context.Database.ExecuteSqlRaw("dbo.SP_Core  @pin_ID={0}", id)
                                 .AsNoTracking().ToList(); //3K line of sp
     return Query;
}

如果可能的话,每当我们更新我认为我们无法做到的代码时,它会自动将DBSet 添加到上下文中。

在没有 dbset 模型的情况下获取查询结果,然后我将使用 foreach 循环将其添加到 FormBO 模型中,它只有 10 行

【问题讨论】:

标签: c# entity-framework-core asp.net-core-3.1


【解决方案1】:

由于该表实际上并不存在于数据库中,因此内置的脚手架进程不会尝试创建它。

但是,您可能可以用扩展 RelationalScaffoldingModelFactory 的实现替换 IScaffoldingModelFactory 服务,并使用代码优先的 fluent api 为实际上不存在的表定义元数据。

您可能可以使用这种方法来定义数据库中所有表值的类型。由于 EF Core 5 正在添加对表值的支持,也许他们会为你做这件事,但我还没有测试过。

public class MyModelFactory : RelationalScaffoldingModelFactory
{
    public MyModelFactory(
        IOperationReporter reporter, 
        ICandidateNamingService candidateNamingService, 
        IPluralizer pluralizer, 
        ICSharpUtilities cSharpUtilities, 
        IScaffoldingTypeMapper scaffoldingTypeMapper, 
        LoggingDefinitions loggingDefinitions) 
    : base(reporter, candidateNamingService, pluralizer, cSharpUtilities, scaffoldingTypeMapper, loggingDefinitions)
    {
    }

    protected override ModelBuilder VisitDatabaseModel(ModelBuilder modelBuilder, DatabaseModel databaseModel)
    {
        modelBuilder.Entity<FormBO>(entity =>
        {
            // ...
        });

        return base.VisitDatabaseModel(modelBuilder, databaseModel);
    }
}

    services.AddDbContextPool<ContextType>(o =>
    {
        o.ReplaceService<IScaffoldingModelFactory, MyModelFactory>();
        // ...
    });

当然也有一个简单的答案。脚手架上下文是一个部分类。只需在另一个源文件中定义您的另一个 DbSet。

【讨论】:

    猜你喜欢
    • 2021-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多