【问题标题】:Scaffold-DbContext SQL Views ? ASP NET CORE 3.1Scaffold-DbContext SQL 视图? ASP 网络核心 3.1
【发布时间】:2020-03-18 14:42:16
【问题描述】:

我需要你的帮助。 我在网上读到,从来没有一种正确的方法可以将视图从 sql 导入我们的 asp.net 核心项目。 你知道在 3.1 版中你能做到吗?如果是这样,怎么做? 对于表,我使用“scaffold-DbContext”命令。 非常感谢!

【问题讨论】:

    标签: c# sql asp.net-core


    【解决方案1】:

    虽然您不能将scaffold-DbContext 用于数据库视图,但您仍然可以在您的.Net Core 项目中使用SQL View。

    假设你有以下 SQL 视图

    CREATE VIEW [dbo].[v_MyTableResult] AS
    
    SELECT 
        SELECT Id, Name FROM MyTable
    
    GO
    

    根据SQL View的结果集新建一个Model类。

    public class MyTableModel
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
    

    在数据库上下文类中,为模型引入属性。

    public virtual DbSet<MyTableModel> MyTableResults { get; set; }
    

    在 OnModelCreating 方法中,配置模型属性

        modelBuilder.Entity<MyTableModel>(entity =>
        {
            entity.HasNoKey();
    
            entity.Property(e => e.Id)
                .HasColumnName("Id");
    
            entity.Property(e => e.Name)
                .HasColumnName("Name");
        });
    

    最后,在需要视图结果的方法中,在 DbSet 属性上调用 FromSqlRaw

        var myTableResults =
            this.MyDbContext.MyTableResults.FromSqlRaw(
                "SELECT * FROM dbo.v_MyTableResult").ToList();
    

    【讨论】:

      【解决方案2】:

      似乎还不支持。有关解决方法,您可以参考

      Is it possible to automatically map a DB view on Entity Framework Core version 2.1?

      【讨论】:

        【解决方案3】:

        可以搭建视图。只需像搭建表格一样使用 -Tables ,只使用视图的名称。例如,如果您的视图名称是“vw_inventory”,则在包管理器控制台中运行此命令(将您自己的信息替换为“我的...”):

        PM> Scaffold-DbContext "Server=MyServer;Database=MyDatabase;user id=MyUserId;password=MyPassword" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Temp -Tables vw_inventory
        

        此命令将在项目的 Temp 目录中创建模型文件和上下文文件。您可以将模型文件移动到模型目录中(记得更改命名空间名称)。您可以从上下文文件中复制您需要的内容并将其粘贴到项目中相应的现有上下文文件中。

        注意:如果您想在使用本地数据库的集成测试中使用您的视图,您需要创建该视图作为您的数据库设置的一部分。如果您要在多个测试中使用视图,请确保添加一个检查视图是否存在。在这种情况下,由于 SQL“创建视图”语句必须是批处理中的唯一语句,因此您需要在存在检查语句中将创建视图作为动态 Sql 运行。或者,您可以运行单独的“if exists drop view...”,然后是“create view”语句,但是如果多个测试同时运行,您不希望在另一个测试正在使用该视图时删除该视图。 示例:

          void setupDb() {
            ...
            SomeDb.Command(db => db.Database.ExecuteSqlRaw(CreateInventoryView()));
            ...
          }
          public string CreateInventoryView() => @"
          IF OBJECT_ID('[dbo].[vw_inventory]') IS NULL
            BEGIN EXEC('CREATE VIEW [dbo].[vw_inventory] AS
               SELECT ...')
            END";
        

        这是一个有用的链接。它描述了手动添加代码部分(如 Nouman 所述)而不是脚手架:https://docs.microsoft.com/en-us/ef/core/modeling/keyless-entity-types?tabs=fluent-api

        【讨论】:

          【解决方案4】:

          我最近有类似的需求(检索一个或多个视图并在 .NET 项目中创建相应的类)。可以通过Scaffold-DbContect来完成,例如:

          Scaffold-DbContext "Server=<address>;
          Database=<dbname>;
          Trusted_Connection=True" 
          Microsoft.EntityFrameworkCore.SqlServer -OutputDir
          ModelDirectory -t <table_name> -t <view_name>
          

          它创建一个名为 OutputDir 的文件夹,其中包含指示的表或视图的相应类

          【讨论】:

            【解决方案5】:

            是的,我们可以使用 scaffold-DbContext with view

            使用scaffold-DbContext 进行数据库视图(myview)。我在下面执行了脚手架-DbContext 查询。

            Scaffold-DbContext "Data Source=my_server,1433;Initial Catalog=my_database;User Id=my_user;Password=my_password;" Microsoft.EntityFrameworkCore.SqlServer -o 实体 -Context ContextName -t myview -f

            一旦你执行,你就会得到实体类和上下文文件。

            实体类 (myview.cs) 中的代码

            ////// Fetching data
            public partial class myview
            { 
                public Guid property_1 { get; set; }
                
            }
            

            dbcontect 文件中的代码 (ContextName.cs)

            public partial class ContextName : DbContext
            {
                public virtual DbSet<myview> myview { get; set; }
                protected override void OnModelCreating(ModelBuilder modelBuilder)
                {
                    modelBuilder.Entity<myview>(entity =>
                    {
                        entity.HasNoKey();
            
                        entity.ToView("myview", "ExtIntDWFS");
            
                        ////// other property configuration.
                    }
                }
            }
            

            控制器中用于获取视图数据的代码

            ////// Fetching data
            public async Task<myview> GetView(Base @base)
                {
                    myview obj = new myview();
            
                    using (ContextName context = new ContextName())
                    {
                        obj = await context.myview.Select(s => new myview
                                                          {
                                                              property_1 = s.property_1,
                                                          }).FirstOrDefaultAsync();
                    }
            
                    return obj;
                }
            

            上面的代码成功地为我工作。

            【讨论】:

              猜你喜欢
              • 2020-10-16
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-03-22
              • 2021-02-01
              • 1970-01-01
              相关资源
              最近更新 更多