EF Core 6-在不更新C#模型的情况下从SQL表中删除列



我有一个具体的EF Core 6.x问题。

如果SQL表中删除了一列。然后EF Core会抛出一个SqlException,说它是一个无效的列名,除非我也更新了C#模型。

例如,

Create Table User
(
FirstName varchar(200)
,MiddleName varchar(200) null -- tried to remove this column after table is created
,LastName varchar(200)
)

我尝试从SQL表中删除MiddleName列。当我使用EF Core 6运行一个简单的读取调用时,我会得到错误。

c#型号

public class User
{
public virtual string FirstName { get; set; }
public virtual string? MiddleName { get; set; }
public virtual string LastName { get; set; }
}

var db = new EFDbContext(connectionString);
var data = db.Users.ToList();  // SqlException here after column removal

有没有什么方法可以在不需要更新c#类的情况下从表中删除列?

尝试使C#属性MiddleName不是虚拟的。

更新:

如果我有一个现有的应用程序。即使代码库没有在任何地方引用删除的列,我也需要修改c#模型。或者,我可以用[NotMapped]装饰属性,或者在模型生成器中使用Ignore((方法。

这两种方法都意味着需要重新构建程序集,并且在部署期间需要停机。

NHibernate的映射可以使用XML文件来完成,因此只需简单的配置文件更新即可。

在EF Core中,我似乎找不到任何东西可以在发生模式更改时减少维护旧代码库的麻烦。

EF在内部创建一个数据模型映射,以跟踪数据库模式和代码模型。通过删除数据库表中的列,代码模型将不再与数据库匹配。因此,出现了异常。

这肯定不是您想要的答案,但据我所知,EF Core需要模型和DB模式之间的一致性才能工作。

我可以在这里想到两件事:

  • 也许你可以从使用不同的ORM中受益(你给Dapper打了电话吗(

  • 如果有多个团队使用同一个数据库,并且有多个系统调用该数据库,那么您可能会面临体系结构问题,避免将来出现麻烦的最佳方法是隔离数据访问层并公开为所有相关系统提供服务的API。这样,如果数据库发生更改,您只需要重新构建数据访问层,而不会让客户端停机。

最后。。。在我看来,理想的解决方案是两者的结合,创建一个解耦的数据访问层,映射那里的内容,并公开一个API和您的应用程序所需的模型。

最新更新