c# - Entity Framework 核心 : Extend Entity without partial

标签 c# .net entity-framework .net-core entity-framework-core

我必须扩展当前数据库实体 ( Foo ) 以包含新字段。听起来很简单,但我很难解决。问题是,我无法为 Foo 创建分部类因为它是我正在使用的 dll 的一部分。而且我无法请求修改 Foo (或由我自己做)如我所愿。

我的项目结构类似于:

// unmodifiable because part of dll
class Foo 
{
    int Id { get; set; }
    string Name { get; set; }
}

// unmodifiable because part of dll
interface IFooContext 
{
     DbSet<Foo> Foo { get; set; }
}

class FooContext: DbContext, IFooContext 
{
     DbSet<Foo> Foo { get; set; }
}

由于我对 .net 的了解有限,我尝试的是创建类 Bar什么扩展Foo并期望实现 IFooContext 就足够了带扩展类 Bar .

您可以在下面看到,但最终会出现错误,因为 C# 不允许使用可用于父级的扩展类。
class Bar: Foo 
{
     string Description { get; set; } //new field
}

class FooLoader: DbContext, IFooContext 
{
     DbSet<Bar> Foo; //error because DbSet<Foo> required
}

我能做的是创建属性 DbSet<Bar> Bar { get; set; }FooLoader ,但是我最终会得到两个几乎相同的数据库表:Foo 和 Bar。

所以我做了修改并创建了类Bar其中将包含 FooId .结果是两个表,其中 Bar表引用了 Foo .
class Bar 
{
     int Id { get; set; }

     Foo Foo { get; set; }
     int FooId { get; set; }

     string Description { get; set; }
}

这两种情况都会创建一个我不确定的新表,如果是我正在寻找的。但是有没有其他方法可以做到这一点并在基类/表中包含新字段?

最佳答案

代码优先方法为您提供了至少 3 个选项来将您的(继承层次结构)实体映射到表:

  • Table per Hierarchy (TPH)
  • Table per Type (TPT)
  • Table per Concrete Type (TPC)

  • 您需要的是第一种方法,它将您的基类和层次映射到一个表,但将添加一个附加列(“鉴别器”作为默认名称)以标识它们的 Type ,当您从数据库中查询整行时,将使用哪一列恢复为其自己的类型。最重要的是:与其他两种方法相比,第一种方法也提供了最佳性能。

    这里有一些很好的帖子,您可以在其中找到实现:
  • https://docs.microsoft.com/en-us/ef/core/modeling/relational/inheritance
  • https://docs.microsoft.com/en-us/aspnet/core/data/ef-mvc/inheritance?view=aspnetcore-3.1
  • https://www.learnentityframeworkcore.com/inheritance/table-per-hierarchy

  • 就是这样:
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        ....
    
        modelBuilder.Entity<Foo>()
                .HasDiscriminator<string>("FooType")
                .HasValue<Foo>(nameof(Foo))
                .HasValue<Bar>(nameof(Bar))
                .HasValue<Other>(nameof(Other));
        ...
        base.OnModelCreating(modelBuilder);
    }
    

    或者
    modelBuilder.Entity<Foo>()
            .HasDiscriminator<int>("FooType")
            .HasValue<Foo>(1)
            .HasValue<Bar>(2)
            .HasValue<Other>(3);
    

    关于c# - Entity Framework 核心 : Extend Entity without partial,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59426530/

    相关文章:

    c# - db.savechanges() 不工作

    c# - 在 Visual Studio 2015+ 中,如何确定哪个对象导致了 null 异常?

    c# - 自定义 RoleProvider 和无法加载类型

    c# - 将其构建为一个语句?

    CS0122 和 CS0143 之间的 C# 编译器错误差异

    c# - 什么是NullReferenceException,如何解决?

    c# - 带有多表插入的 EntityFramework 事务回滚

    c# - WP8 - Facebook 登录问题

    c# - 刚体圆周运动

    .net - WiX - 安装 Windows 服务以在 x64 模式下运行