我必须扩展当前数据库实体 ( 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 个选项来将您的(继承层次结构)实体映射到表:
您需要的是第一种方法,它将您的基类和层次映射到一个表,但将添加一个附加列(“鉴别器”作为默认名称)以标识它们的
Type
,当您从数据库中查询整行时,将使用哪一列恢复为其自己的类型。最重要的是:与其他两种方法相比,第一种方法也提供了最佳性能。这里有一些很好的帖子,您可以在其中找到实现:
就是这样:
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/