实体框架+多级继承+EF代码优先

2023-12-01

我正在尝试使用 Code First 设置 TPC 继承。我有三级继承权。 抽象类A,具体类B继承自A,类C继承自B。 A 类属性:ID、CreatedBy 和 CreatedOn。 B 类属性:FirstName、LastName、BirthDate C 类属性:约会日期、状态

我希望在数据库中创建 B 类和 C 类的表,并使用数据库生成的标识。

我的上下文类中有以下代码:

public DbSet<B> BList { get; set; }
public DbSet<C> CList { get; set; }

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<B>().ToTable("BClass");
        modelBuilder.Entity<C>().ToTable("CClass");
    }

我有一个 contextinitializer 类,它重写 Seed 方法以填充数据库中的一些测试数据。

protected override void Seed(TestContext context)
    {
        TestDataClass testData = new TestDataClass();

        List<B> bList= testData.GetBList();

        foreach (B objB in bList)
        {
            context.BList.Add(objB);
        }

        List<C> cList = testData.GetCList();
        foreach (C objC in cList)
        {
            context.CList.Add(objC);
        }

        context.SaveChanges();
    }

这会在数据库中创建表 BClass 和 CClass,但问题是,如果我在 BClass 中插入 10 行并在 CClass 中插入相应的 10 行,则实体框架会在 BClass 中插入 20 行,其中 10 行包含实际值,10 行包含 Null。 CClass 给出了 10 行的预期结果。 第二个问题是当我从CClass查询数据时没有得到结果。我的错误消息说:

EntitySet“CClass”未在 EntityContainer 中定义 '测试上下文'。靠近简单标识符,第 1 行,第 12 列。

我正在使用 Huy Nguyen 的 Entity Framework 4 POCO、存储库和规范模式 [升级到 EF 4.1] 帖子中的代码http://huyrua.wordpress.com/2011/04/13/entity-framework-4-poco-repository-and-specification-pattern-upgraded-to-ef-4-1/我在通用存储库中的代码看起来像

public IList<TEntity> FindAll<TEntity>() where TEntity : class
    {
        DbContext.Set<TEntity>();
        var entityName = GetEntityName<TEntity>();
        return ((IObjectContextAdapter)DbContext).ObjectContext.CreateQuery<TEntity>(entityName).ToList<TEntity>();
    }

        private string GetEntityName<TEntity>() where TEntity : class
    {
        DbContext.Set<TEntity>();
        return string.Format("{0}.{1}", ((IObjectContextAdapter)DbContext).ObjectContext.DefaultContainerName, _pluralizer.Pluralize(typeof(TEntity).Name));
    }

我尝试更改表映射,但没有帮助。我不知道我在这里错过了什么,也不知道该怎么做。我急需帮助。

提前致谢。


这就是我的实际课程的样子:

public abstract class EntityBase
{
    [DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.Identity)]
    public virtual long Id { get; set; }
    public virtual string CreatedBy { get; set; }
    public virtual DateTime? CreatedOn { get; set; }
    public virtual string LastModifiedBy { get; set; }
    public virtual DateTime? LastModifiedOn { get; set; }

}


public class Person: EntityBase
{
    public virtual string FirstName { get; set; }
public virtual string MiddleName { get; set; }
    public virtual string LastName { get; set; }
    public virtual DateTime? BirthDate { get; set; }


    [NotMapped]
    public virtual string FullName
    {
        get
        {
            return String.Format("{0}, {1} {2}", LastName, FirstName, MiddleName);
        }
    }
}

public partial class Employee : Person
{
[Required]
    public string EmployeeNumber { get; set; }
[Required]
public string department { get; set; }

    public  DateTime? JoiningDate { get; set; }
    public  DateTime? PromotionDate { get; set; }
 }

我的上下文类现在有:

public DbSet<EntityBase> People { get; set; }

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<Person>().ToTable("Person");
        modelBuilder.Entity<Employee>().Map(m => m.MapInheritedProperties()).ToTable("Employee"); 
}

您的映射指定 TPT 而不是 TPC。您必须使用:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    modelBuilder.Entity<B>().ToTable("BClass"); 
    modelBuilder.Entity<C>().Map(m => m.MapInheritedProperties()).ToTable("CClass");
}

我希望在数据库中创建 B 类和 C 类的表 具有数据库生成的身份。

EF 不会为您做这件事。这将需要对生成的代码进行自定义修改,因为一旦使用继承实体,整个继承层次结构中的所有实例之间必须具有唯一的 ID = B 表和 C 表之间的 id 必须是唯一的。通过为 B 指定标识为种子 0 和增量 2,为 C 指定标识为种子 1 和增量 2,可以轻松完成此操作,但每次添加新的子实体类型时都必须修改此设置。

你的存储库太糟糕了。为什么在使用 DbContext 时要转换回 ObjectContext?阅读有关使用和查询 DbContext 的内容,并从不使用存储库的情况开始。此外,ObjectContext API 不允许在查询中使用派生类型。您必须查询顶级映射实体类型和使用OfType扩展方法仅获取派生类型。

var cs = objectContext.CreateSet<B>().OfType<C>().ToList();

这是通用方法不起作用的另一个例子。

Edit:

抱歉,我知道问题出在哪里了。我的描述太快了,我跳过了解决方案的一个重要细节。我没有A(EntityBase)映射,因为不需要它。它被标记为抽象实体,因此不需要为 TPC 继承中始终为空的实体建立单独的表。这也是我的B(Person) 不打电话MapInheritedProperties在它的映射中,因为我将它作为映射继承的根。因此,我为示例定义的 DbSet 必须定义为:

public DbSet<Person> People { get; set; }

如果你想定义DbSet<EntityBase>你必须绘制地图Person在相同的方式Employee:

modelBuilder.Entity<Person>().Map(m => m.MapInheritedProperties()).ToTable("Person"); 

您当前的映射定义EntityBase and Person作为 TPT 继承的一部分Employee作为 TPC 继承,但 EF 不喜欢组合继承类型。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

实体框架+多级继承+EF代码优先 的相关文章

随机推荐

  • 当父级有修饰符时,SCSS + BEM 风格的子级结构

    请问可以为 rounded 内的元素设置 css 吗 我不想使用 box 某些东西 但我需要修改依赖于父修饰符的子项 div class box div class box something Hello div div div class
  • 使用AWS iOS SDK从cloudfront分发中获取文件

    我正在使用适用于 AWS 的最新 iOS SDK 并且使用 TransferManager 类从 S3 获取文件可以正常工作 S3GetObjectRequest request S3GetObjectRequest alloc initW
  • 在 Socket.IO 1.0 中配置超时和传输

    在旧版本的 Socket IO io set transports xhr polling io set close timeout 3 但现在 命令io set已被弃用 我如何定义close timeout and transports
  • Bing 地图 GetRoute 给出“0x8004231C”错误

    我试图在 bing 地图上显示从点到点的路线 在真实设备上测试 我已经输入了 2 个航路点 地理坐标 并且我正在尝试使用以下命令通过 Windows PhoneToolKit 获取路线await query GetRouteAsync 不幸
  • 强制乘法使用 __rmul__() 而不是 Numpy 数组 __mul__() 或绕过广播

    这个问题与中提出的问题很接近用你班级的 mul 覆盖其他 rmul 但我的印象是 这是一个比数值数据更普遍的问题 这也没有得到解答 我真的不想使用矩阵乘法 对于此操作 因此 问题 我确实有一个接受标量和数值数组相乘的对象 像往常一样 左乘法
  • Android 自定义日历和提醒[关闭]

    Closed 这个问题需要多问focused 目前不接受答案 我的应用程序将包含一个自定义日历 并且根据此日历用户可以创建事件和提醒 问题是 是否可以在 android 中创建自定义日历 我的意思是我想在我的日历中创建事件 这些事件不会出现
  • javascript回调函数,变量映射

    我一直在javascript中使用回调函数 但我从来不明白回调如何知道它可以接受哪些变量 让我们看下面的示例代码 var friends Mike Stacy Andy Rick friends forEach function name
  • 我是否必须修复最新 nuxt.js 的审核问题?

    我正在尝试在我的应用程序中使用 nuxt 但是当我运行 yarn 审计 时 存在一些审计问题 这些问题是 nuxt 的依赖项 我必须解决这些审计问题吗 如果必须的话 我该如何解决它 我正在使用 nuxt 2 15 7 并且添加了最新的css
  • GWT 有哪些效果库可用于商业用途?

    我正在寻找一个可以非常非常轻松地放入我现有的 GWT 应用程序的效果库 我想将库添加到我的构建路径中 然后开始编写类似的内容FX fadeOut thisWidget 取代thisWidget setVisible false GWT 是否
  • Spring Data JDBC 使用 Boot 2.3.0 生成错误的 HSQLDB 查询

    我有一个使用 Spring Data JDBC 的 Spring Boot 项目 测试使用 HSQLDB 当我尝试升级到 Spring Boot 2 3 0 时 我的存储库测试开始失败 Spring Data JDBC 现在似乎引用表名和列
  • 如何在 localhost 中通过 node.js 使用 webodf 编辑器

    我没有找到任何关于如何运行 webodf 的教程 我阅读了他的 api 和源代码 我正在了解如何启动它 任何人都可以分享这个想法 WebODF version 0 5 10 8 gf5949f3 Found Java usr bin jav
  • 在php中,二维数组的行数和列数?

    我有一个元素数量未知的二维数组 two darray row column there will be an unknown integer values instead of row and column keywords 如果我要写一个
  • 创建仅包含整数的列表

    我正在尝试创建一个仅包含另一个列表中的整数的列表 假设我的范围列表是 我希望结果显示为 我希望该解决方案仅适用于 Excel 2019 任何帮助将不胜感激 谢谢 如果您有 Office 365 您可以使用 FILTER A1 A6 INT
  • WTForms 错误:TypeError:formdata 应该是多字典类型包装器

    from wtforms import Form BooleanField TextField validators PasswordField class LoginForm Form username TextField Usernam
  • 短代码呈现为文本而不是短代码应有的形式

    我正在建立一个购物网站 我试图在其中添加一个短代码 该代码将向客户显示购买按钮以及客户想要购买的产品数量 在我的帖子页面上 短代码工作正常 http warringah Plastics com au blog dt catalog rec
  • 计算 iOS 的 CoreMIDI 弯音值?

    我需要手工组装14位MIDI 弯音来自 iOS 中原始 UInt16 值的值 我想知道是否有人有机会提出一个优雅的解决方案 这就是我现在的情况 我可能会在今天晚些时候有机会对此进行测试 但如果我在那之前收到回复 那就太好了 首先 为好奇的人
  • 序列化 CDT 项目设置时遇到了

    当我构建项目时 我收到此错误 Serializing CDT Project settings has encountered a problem Null Pointer Exception 我正在使用最新的 eclipse 并尝试为 A
  • CSS 中的 > 和 ~ 表达式

    CSS 中 和 gt 的用途是什么 例如下面的表达式是什么意思 checked label content gt 您的选择器意味着 选择任意元素这是该类元素的子元素content接下来是label这又遵循 checked输入元素 gt is
  • 如何检查一个列表是否包含另一个列表的所有元素(包括重复项)

    e g t A A A b b s A A b b s 并不包含 t 中的每个元素 t 包含 s 中的每个元素 我想出了这个 但想知道是否有更有效的方法 def check l1 l2 for i in l2 if l2 count i g
  • 实体框架+多级继承+EF代码优先

    我正在尝试使用 Code First 设置 TPC 继承 我有三级继承权 抽象类A 具体类B继承自A 类C继承自B A 类属性 ID CreatedBy 和 CreatedOn B 类属性 FirstName LastName BirthD