无法在 ADO .NET 实体模型 edmx 中的类继承中执行覆盖

Posted

技术标签:

【中文标题】无法在 ADO .NET 实体模型 edmx 中的类继承中执行覆盖【英文标题】:cannot perform override in class inheritance in ADO .NET Entity Model edmx 【发布时间】:2022-01-17 02:35:02 【问题描述】:

我必须构建一个访问现有数据库表的 .net Web 应用程序。

数据库为不同的公司使用不同的表:公司“ACorp”中的客户存储在表“ACorpCustomers”中,公司“B”中的客户存储在表“BCorpCustomers”中。

使用 ADO .NET 实体模型,我为每个公司创建了不同的 Db 上下文:

public partial class ACorpContext : DbContext
    
        public ACorpContext()
            : base("name=ACorpContext")
        
        
    
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        
            throw new UnintentionalCodeFirstException();
        
    
        public virtual DbSet<ACorpCustomer> ACorpCustomers  get; set; 
    

edmx 也生成类

public partial class ACorpCustomer

    public string Name  get; set; 
    public string Phone  get; set; 

我创建了一个父类 Customer 以在应用程序中使用,具有相同的属性:

public class ACorpCustomer

    public virtual string Name  get; set; 
    public virtual string Phone  get; set; 

我还没有找到让特定实体 ACorpCustomers 从父客户继承的方法; edmx 返回继承错误,但无法覆盖属性。

更新

为了避免使用edmx文件,我最后试了一下:

    我使用 AutomaticMigrationsEnabled 参数禁用了 __MigrationHistory sql 表创建:

         internal sealed class Configuration : DbMigrationsConfiguration<MyDomain.Models.ACorpContext>
         
             public Configuration()
             
                 AutomaticMigrationsEnabled = false;
             
         
    

    我在 App.config 文件设置中禁用了数据库初始化 disableDatabaseInitialization="true"

    然后我添加了一个 ADO .NET 实体模型,但选择了“首先来自数据库的代码”。 为了确保不改变模型中的数据库,我禁用了数据库初始化器:

         public ACorpContext()
             : base("name=ACorpContext")
         
             Database.SetInitializer<ACorpContext>(null);
         
    

现在我希望我的职责是使域模型与数据库保持同步。 无论如何,我确信如果发生错位,不会尝试修改数据库。 如果没有 edmx,我在定义从抽象类 Customer 继承时就没有更多限制了。

无论如何,我无法理解为什么 Visual Studio 认为这是“代码优先”的方法。

【问题讨论】:

【参考方案1】:

你的定义

public partial class ACorpCustomer

与继承无关。 partial 是 .NET 版主,表示您的类定义是更大定义的一部分。例如,如果您将类拆分为 2 个代码文件。 .Net 将它们“组合”在一起,最终得到一个 type

你似乎需要做的是


public abstract class Customer

    public string Name  get; set; 
    public string Phone  get; set; 


public class ACorpCustomer : Customer

    // may be, some unique properties here


public class BCorpCustomer : Customer

    // may be, some unique properties here


属性NamePhone 甚至不需要是virtual。回顾你的标题,你不需要override。我什么都没看到..

【讨论】:

admx 强制使用其属性创建类 ACorpCustomer,并且建议不要手动修改它,因为每次 admx 与 db 结构同步时它都会被覆盖。因为类被 edmx 定义为部分类,所以我可以将它与继承集成,但我不能删除或覆盖任何属性。 @AndreaRossi 进行全面披露,我从未使用过 Code-First 方法。只有 DB 优先。我们手动设置了所有模型并使用了不同的技术,如拆分表、继承等。所以,我现在无法很好地判断代码优先【参考方案2】:

这在 Code-First 中是微不足道的,您可以(并且应该)将其与 existing database 一起使用。只需将单个 Customer 实体映射到每个 DbContext 的正确表:

    public partial class ACorpContext : MyBaseDbContext
    
    
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        
            modelBuilder.Entity<Customer>().ToTable("ACorpContext");
        
    
        public virtual DbSet<Customer> Customers get; set; 
    

【讨论】:

使用这个解决方案我不得不使用 __MigrationHistory 表;但在这个项目中,我无法向该数据库添加任何表。我需要的是一种纯数据库优先的方法。 您不需要使用这种方法进行迁移。

以上是关于无法在 ADO .NET 实体模型 edmx 中的类继承中执行覆盖的主要内容,如果未能解决你的问题,请参考以下文章

VS2010里创建ado.net实体模型,根据实体对象创建数据库, 会生成一个.edmx.sql这个文件

同一个 .net 解决方案中的多个 edmx

ORACLE 数据提供程序未显示为选项

添加 ADO.NET 实体模型崩溃

如何从 ADO.NET Entity Framework 中的模型生成表?

请问VS中的ADO.NET实体数据模型怎么添加?我在VS的联网模版里没找到