c# - CTP 4 不考虑基类属性

标签 c# .net entity-framework ctp4

在下面的示例中,CTP 仅考虑用户类属性,但我希望用户表中包含基类属性。

有没有办法告诉 CTP 包含基类属性?或者有什么替代解决方案?

class PersonDBContext : DbContext
{
    public DbSet<User> UserSet { get; set; }
}
class Person
{
    public string Firstname { get; set; }
    public string SurName { get; set; }
}
class User : Person
{
    public int UserId { get; set; }
    public string CreatedOn { get; set; }
}

最佳答案

那是因为你声明了 DbSet<User>在您的 DbContext 而不是 DbSet<Person> 中。当涉及到继承时,EF 代码首先有一个可达性的概念,这基本上意味着如果您将一组基类放入上下文中,它将向下查找并包含其所有子类。

这里还有一个问题:您还没有为 Person 指定主键class 和 EF 也无法根据 Code First 约定推断出类。默认情况下,EF 将模型中的继承映射到数据库中的 TPH(每个层次结构的类型),并且子类从其基类继承键,该基类已放入模型中的子类(即 UserId)中。

要解决此问题,我们首先将 DbContext 上的 DbSet 更改为 Person 类型然后我们需要向上移动UserIdPerson基类并将其设为Key,如下所示:

public class Person 
{
    [Key]
    public int UserId { get; set; }

    public string Firstname { get; set; }
    public string SurName { get; set; }
}

public class User : Person 
{        
    public string CreatedOn { get; set; }
}

public class PersonDBContext : DbContext 
{
    public DbSet<Person> UserSet { get; set; }        
}

此模型将生成以下数据库架构,其中包含两个类的所有列(注意复数支持):

alt text

如何在 Code First 中将 TPH 更改为 TPT(每个层次结构表):

就像我说的,按照惯例,EF 代码首先将使用 TPH 将继承映射到数据库,并将其更改为 TPT,我们需要使用 Fluent API 覆盖约定:

public class StackOverflowContext : DbContext
{
    public DbSet<Person> Persons { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Person>().MapHierarchy(p => new
        {
            p.UserId,
            p.Firstname,
            p.SurName,
        })
        .ToTable("Person");

        modelBuilder.Entity<User>().MapHierarchy(u => new
        {
            u.UserId,
            u.CreatedOn
        })
        .ToTable("User");
    }
}

此模型将产生以下数据库架构:

alt text

如何在 Code First 中将 TPH 更改为 TPC(每种混凝土类型表):

在每个具体类的表中,每个类都有一个表,并且每个表都有一个用于该类型的每个属性的列。

其代码如下所示,请注意,我关闭了主键属性上的标识,因为两个表之间没有外键,我们需要提供唯一键。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Person>().Property(p => p.UserId)
    .StoreGeneratedPattern = System.Data.Metadata.Edm.StoreGeneratedPattern.None;

    modelBuilder.Entity<Person>().MapSingleType(p => new
    {
        p.UserId,
        p.Firstname,
        p.SurName,
    })
    .ToTable("Person");

    modelBuilder.Entity<User>().MapSingleType(u => new
    {
        u.UserId,
        u.CreatedOn,
        u.Firstname,
        u.SurName,
    })
    .ToTable("User");
}

此模型将产生以下数据库架构: alt text

关于c# - CTP 4 不考虑基类属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4362641/

相关文章:

c# - 在模型上使用 DateTime.UtcNow 总是在实体中创建迁移

entity-framework - 通过接口(interface)属性 LINQ to Entities

c# - Entity Framework 继承

c# - 将字符串转换为十进制分隔符 "."和 ","不敏感方式的最佳方式?

c# - 在多线程环境中创建实例

c# - 根据范围数据查找值

.net - 如何创建与 Excel 一起使用的数据提供程序

.net - 没有数据库的 WPF 的最佳报告引擎?

c# - 无法使用 C# HttpClient 上传文件,Postman 工作正常

c# - 是否可以将 HttpModule 添加到 ASP Classic 应用程序?