首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Pomelo & EFCore在迁移中不忽略视图

Pomelo & EFCore在迁移中不忽略视图
EN

Stack Overflow用户
提问于 2021-06-10 10:38:57
回答 2查看 451关注 0票数 1

我有一个使用EFCore和Pomelo.EntityFrameworkCore的dotnet核心项目。我刚刚更新了EFCore 3.1.0到5.0.7 (最迟在撰写本文时),同时还更新了Pomelo到5.0.0

在我的项目中,我使用EFCore调用存储过程并将它们映射到视图。我将视图添加到上下文中如下:

代码语言:javascript
复制
modelBuilder.Entity<NameOfView>().HasNoKey().ToView(null);

更新EFCore和Pomelo之后,我现在注意到的是,每当我尝试运行迁移时,它就不再忽略这些视图。我一直在迁移中获取CreateTableDropTable脚本,这取决于视图是否在数据库快照中。在更新之前,这些视图被忽略了。

是否需要为上下文中的视图设置一些属性,以确保它们被忽略?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-06-10 12:29:40

您正在经历下面的EFCore5.0破坏更改迁移对ToView()的处理方式不同,特别是在这里解释的升级行为之后的第一次迁移

新行为 现在,除了将实体类型映射到视图之外,ToView(string)还将实体类型标记为未映射到表。这将导致升级到EF Core 5以尝试删除该实体类型的默认表之后的第一次迁移,因为它不再被忽略。

我可以理解更改fluent API行为的理由,但不理解迁移行为(hello,向后兼容性?)。和建议的“缓解”

使用以下代码将映射表标记为不允许迁移: 保护覆盖无效OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity().ToTable("UserView",t => t.ExcludeFromMigrations());}

虽然它似乎修复了升级行为之后的第一次迁移,但它需要指定假表名。不幸的是,带有ToTable功能的ExcludeFromMigrations方法重载不接受null表名。

我建议的解决办法似乎既适用于已退出的实体,也适用于新的“未映射”实体,它将取代

代码语言:javascript
复制
.ToView(null)

使用

代码语言:javascript
复制
.HasAnnotation(RelationalAnnotationNames.IsTableExcludedFromMigrations, true)

注意:这是EF核心通用问题,而不是特定于数据库提供程序的问题,因此与MySQL或Pomelo无关。

票数 3
EN

Stack Overflow用户

发布于 2021-06-10 11:48:24

这似乎与Pomelo或EF Core没有什么关系,因为以下内容确实如预期的那样工作:

  1. 创建一个具有以下内容的项目:

Project.csproj

代码语言:javascript
复制
<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net5.0</TargetFramework>
        <Nullable>disable</Nullable>
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.7">
            <PrivateAssets>all</PrivateAssets>
            <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
        </PackageReference>
        <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="5.0.0" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="5.0.7" />
        <PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="5.0.0" />
    </ItemGroup>

</Project>

Program.cs

代码语言:javascript
复制
using System;
using System.Diagnostics;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

namespace IssueConsoleTemplate
{
    public class IceCream
    {
        public int IceCreamId { get; set; }
        public string Name { get; set; }
        public DateTime BestServedBefore { get; set; }
    }

    public class ExpiredIceCream
    {
        public int IceCreamId { get; set; }
        public string Name { get; set; }
        public DateTime BestServedBefore { get; set; }
        public int DaysExpired { get; set; }
    }

    public class Context : DbContext
    {
        public DbSet<IceCream> IceCreams { get; set; }
        public DbSet<ExpiredIceCream> ExpiredIceCreams { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
            {
                var connectionString = "server=127.0.0.1;port=3306;user=root;password=;database=So67919519_01";
                var serverVersion = ServerVersion.AutoDetect(connectionString);
                optionsBuilder.UseMySql(connectionString, serverVersion)
                    .UseLoggerFactory(
                        LoggerFactory.Create(
                            configure => configure
                                .AddConsole()
                                .AddFilter(level => level >= LogLevel.Information)))
                    .EnableSensitiveDataLogging()
                    .EnableDetailedErrors();
            }
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<IceCream>()
                .HasData(
                    new IceCream {IceCreamId = 1, Name = "Vanilla", BestServedBefore = new DateTime(2021, 1, 1)},
                    new IceCream {IceCreamId = 2, Name = "Chocolate", BestServedBefore = new DateTime(2021, 5, 15)},
                    new IceCream {IceCreamId = 3, Name = "Matcha", BestServedBefore = DateTime.Today.AddYears(5)});

            modelBuilder.Entity<ExpiredIceCream>(
                entity =>
                {
                    entity.ToView("ExpiredIceCreams");
                    entity.HasNoKey();
                });
        }
    }

    internal static class Program
    {
        private static void Main()
        {
            using var context = new Context();

            var expiredIceCreams = context.ExpiredIceCreams.ToList();
            
            Trace.Assert(expiredIceCreams.Count == 2);
        }
    }
}

创建初始迁移:

代码语言:javascript
复制
dotnet ef migrations add Initial

将以下代码添加到生成的Up()文件中的Migrations/..._Initial.cs方法的末尾:

代码语言:javascript
复制
migrationBuilder.Sql(@"
    CREATE VIEW `ExpiredIceCreams` AS
        SELECT *, DATEDIFF(CURDATE(), `BestServedBefore`) AS DaysExpired
        FROM `IceCreams`
        WHERE `BestServedBefore` <= CURDATE();");

将以下代码添加到生成的Down()文件中的Migrations/..._Initial.cs方法的开头:

代码语言:javascript
复制
migrationBuilder.Sql(@"DROP VIEW `ExpiredIceCreams`;");

更新数据库:

代码语言:javascript
复制
dotnet ef database update

运行该项目以确保其按预期工作。

然后添加第二次迁移:

代码语言:javascript
复制
dotnet ef migrations add Second

查看生成的Migrations/..._Second.cs文件。它不应该包含任何有关ExpiredIceCreams视图的操作。

从这里往哪里去

首先,我会对新旧的...<MigrationName>.Design.cs文件进行区分,看看到底发生了什么。

可以随意发布迁移文件的内容,这样我们就可以查看它了。

(可能这与某些字符集或排序规则问题/更改有关。)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67919519

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档