简体   繁体   English

Entity Framework Core 从存储过程中获取数据,然后在没有 DbSet 的情况下转换为视图模型

[英]Entity Framework Core get data from stored procedure and then convert into view model without DbSet

I have a function in the repository, GetForms , the purpose of the function is to call a stored procedure and return rows with data.我在存储库中有一个函数GetForms ,该函数的目的是调用存储过程并返回包含数据的行。 Everything is working fine until now.到目前为止一切正常。

Function功能

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;
}

Model模型

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

DbContext数据库上下文

Added this code, so context thinks it is a table in the database and, I don't have to do more stuff添加了这段代码,所以上下文认为它是数据库中的一个表,我不必做更多的事情

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

The problem问题

Whenever we scaffold the database and the db context, it regenerates all the files and code, so it removes the每当我们构建数据库和 db 上下文时,它都会重新生成所有文件和代码,因此它删除了

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

And we have to add this line manually is there any way I can change the logic, so I don't have to add this code ( DBset<FormBO> ) to DbContext every time a dba updates the database...我们必须手动添加这一行,有什么办法可以改变逻辑,所以每次 dba 更新数据库时,我都不DBset<FormBO>此代码( DBset<FormBO> )添加到DbContext ...

What I found我发现了什么

I found that if I change the model to ".Database" and FromSqlRaw to ExecuteSqlRaw , but it is just returning the count as int not a list of rows.我发现如果我将模型更改为 ".Database" 并将FromSqlRawExecuteSqlRaw ,但它只是将计数返回为 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;
}

If it is possible it automatically add the DBSet to context whenever we update the code which I don't think we will able to do.如果可能的DBSet ,每当我们更新我认为我们无法做到的代码时,它会自动将DBSet添加到上下文中。

or或者

Get the query result without the dbset model and then I will use foreach loop to add it in FormBO model it is just 10 rows获取没有 dbset 模型的查询结果,然后我将使用 foreach 循环将其添加到 FormBO 模型中,它只有 10 行

Since the table doesn't actually exist in the database, the built in scaffolding process won't attempt to create it.由于该表实际上并不存在于数据库中,因此内置的脚手架过程不会尝试创建它。

However you could probably replace the IScaffoldingModelFactory service, with an implementation that extends RelationalScaffoldingModelFactory , and use the code-first fluent api to define meta data for tables that don't really exist.但是,您可能可以使用扩展RelationalScaffoldingModelFactory的实现替换IScaffoldingModelFactory服务,并使用代码优先的 fluent api 为实际上并不存在的表定义元数据。

You could probably use this type of approach to define types for all table values in the database.您可能可以使用这种类型的方法为数据库中的所有表值定义类型。 Since EF Core 5 is adding support for table values, maybe they'll do it for you, but I haven't tested that.由于 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>();
        // ...
    });

Of course there's an easy answer too.当然也有一个简单的答案。 The scaffolded context is a partial class.脚手架上下文是一个部分类。 Just define your other DbSet in another source file.只需在另一个源文件中定义其他 DbSet。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM