使用EF Core Code First方法创建数据库视图

时间:2019-11-04 13:00:04

标签: entity-framework entity-framework-core

我正在开发一个需要创建数据库视图的新应用程序。我正在使用具有MySql风格的EF核心,并使用了代码优先方法来创建数据库和表。我没有找到创建视图的方法,如果可以的话,我可以在迁移步骤中执行原始sql,这可能有助于创建视图并将其映射为DbSet。我无法手动创建视图,因为这将需要针对数据库执行视图脚本,而在更高的环境中将无法实现。有人可以指导我吗?非常感谢您的帮助!

3 个答案:

答案 0 :(得分:1)

据我所知,您不能直接使用EF Core创建视图。但是,升级时可以使用迁移来执行任意SQL。

  1. 即使没有任何实际操作,也可以在程序包管理器控制台中生成迁移:add-migration CreatingTheView
  2. 打开生成的迁移类,文件名:Migrations\yyyyMMdd_CreatingTheView.cs
  3. 通过修改Up方法:migrationBuilder.Sql("CREATE VIEW etc.");
  4. ,添加要在升级时执行的原始SQL。
  5. 如果要支持降级,请修改Down方法:migrationBuilder.Sql("DROP VIEW etc.");

答案 1 :(得分:0)

由于您使用的是Code First,因此数据库可能只是应用程序的扩展,而不是其主要目标?在这种情况下,您可能实际上并不需要视图。

该数据库将不在乎您是否仅向其发送普通查询,并且您可以通过其他方法在应用程序层中抽象它们。最基本的技巧是在您的IQueryable<T>实现(或扩展方法)中创建一个DbContext属性,该属性查询您希望显示的数据。像这样:

public sealed class DatabaseContext : DbContext
{
    public DbSet<Transaction> Transactions { get; set; }

    public IQueryable<PerPersonSum> PerPersonSums
        => Transactions.GroupBy(t => t.Person,
                                (k, g) => new PerPersonSum
                                {
                                    Person = k,
                                    TotalAmount = g.Sum(t => t.Amount)
                                });
}

更合适的解决方案是keyless entity type

public sealed class DatabaseContext : DbContext
{
    public DbSet<Transaction> Transactions { get; set; }

    public DbSet<PerPersonSum> PerPersonSums { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<PerPersonSum>(e =>
        {
            e.HasNoKey();
            e.ToQuery(() => Transactions.GroupBy(t => t.Person,
                                                 (k, g) => new PerPersonSum
                                                 {
                                                     Person = k,
                                                     TotalAmount = g.Sum(t => t.Amount)
                                                 }));
        });
    }
}

3.0之前的版本,它以前被称为查询类型,可以这样使用:

public sealed class DatabaseContext : DbContext
{
    public DbSet<Transaction> Transactions { get; set; }

    public DbQuery<PerPersonSum> PerPersonSums { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Query<PerPersonSum>()
                    .ToQuery(() => Transactions.GroupBy(t => t.Person,
                                                        (k, g) => new PerPersonSum
                                                        {
                                                            Person = k,
                                                            TotalAmount = g.Sum(t => t.Amount)
                                                        }));
    }
}

答案 2 :(得分:0)

来自 relative_random 的答案几乎对我有用,但我必须使用此语法才能使其正常工作:

migrationBuilder.Sql(@"exec('create view dbo.MyViewName as ....');");

migrationBuilder.Sql("exec('drop view dbo.MyViewName');");

如果没有,我会收到一个 sql 错误“创建视图必须是批处理中的唯一语句”。