实体框架 Fluent API 不考虑基类属性

2023-12-04

EF 6.1 :

我们刚刚启动了一个有很多继承的项目。选定的继承数据库映射类型是每个层次结构的表。问题是,当尝试使用 add-migration 生成迁移时,会引发以下错误:

The foreign key component 'VersionId' is not a declared property on type 'SER'. Verify that it has not been explicitly excluded from the model and that it is a valid primitive property.

以下是使用的类和配置类:

public class Version : BaseObject
{
    public virtual ICollection<SER> ListOfSER { get; set; }
}

public abstract class AbsractR : BaseObject
{
    public int ParentId { get; set; }
    public int ChildId { get; set; }

    public int VersionId { get; set; }
    public virtual Version Version { get; set; }
}

public class SER : AbstractR
{
    public int SEDId
    {
        get
        {
            return base.ChildId;
        }
        set
        {
            base.ChildId = value;
        }
    }
    public virtual SED SED { get; set; }
}

public abstract class AbstractD : BaseObject
{
}

public class SED : AbstractD
{
    public virtual ICollection<SER> ListOfSER { get; set; }
}


public class SDContext : BaseContext
{
    public DbSet<Version> Versions { get; set; }
    public DbSet<AbstractD> Ds { get; set; }
    public DbSet<AbstractR> Rs { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Configurations.Add(new VersionConfiguration());

        #region Refs
        modelBuilder.Configurations.Add(new AbstractRConfiguration());
        modelBuilder.Configurations.Add(new SERConfiguration());
        #endregion

        #region Defs
        modelBuilder.Configurations.Add(new AbstractDConfiguration());
        modelBuilder.Configurations.Add(new SEDConfiguration());
        #endregion
    }
}

public class BaseObjectConfiguration<T> : EntityTypeConfiguration<T> where T : BaseObject
{
    public BaseObjectConfiguration()
    {
        #region Key
        this.HasKey(bo => bo.Id);
        #endregion

        #region Properties
        this.Property(bo => bo.Id).IsRequired();
        this.Property(bo => bo.IsDeleted).IsRequired();
        this.Property(bo => bo.LastModificationDate).IsOptional();
        this.Property(bo => bo.OptimisticVersion).IsConcurrencyToken().IsRequired().IsRowVersion();
        this.Property(bo => bo.CreationDate).IsRequired();
        this.Property(bo => bo.DeletionDate).IsOptional();
        #endregion
    }
}

public class VersionConfiguration : BaseObjectConfiguration<Version>
{
    public VersionConfiguration() : base()
    {
        #region Properties
        #endregion

        #region Objects
        this.HasMany(mdv => mdv.ListOfSER).WithRequired().HasForeignKey(ser => ser.VersionId).WillCascadeOnDelete(false);
        #endregion

        #region Table
        this.ToTable("Versions");
        #endregion
    }
}

public class AbstractRConfiguration : BaseObjectConfiguration<AbstractR>
{
    public AbstractRConfiguration()
        : base()
    {
        #region Properties
        this.Property(ser => ser.VersionId).IsRequired();
        #endregion

        #region Objects
        this.HasRequired(ar => ar.Version).WithMany().HasForeignKey(ar => ar.VersionId).WillCascadeOnDelete(false);
        #endregion

        #region Table
        this.ToTable("Refs");
        #endregion
    }
}

public class SERConfiguration : BaseObjectConfiguration<SER>
{
    public SERConfiguration()
        : base()
    {
        #region Properties
        this.Ignore(ser => ser.SEDId);
        #endregion

        #region Objects
        this.HasRequired(ser => ser.SED).WithMany(sed => sed.ListOfSER).HasForeignKey(ser => ser.ChildId).WillCascadeOnDelete(false);
        #endregion

        #region Table
        this.ToTable("Refs");
        #endregion
    }
}

public class AbstractDConfiguration : BaseObjectConfiguration<AbstractD>
{
    public AbstractDConfiguration() : base()
    {
        this.ToTable("Defs");
    }
}

public class SEDConfiguration : BaseObjectConfiguration<SED>
{
    public SEDConfiguration()
        : base()
    {
        #region Properties
        #endregion

        #region Objects
        this.HasMany(sed => sed.ListOfSER).WithRequired(sed => sed.SED).HasForeignKey(sed => sed.ChildId).WillCascadeOnDelete(false);
        #endregion

        #region Table
        this.ToTable("Defs");
        #endregion
    }
}

我知道我们可以使用 [ForeignKey] 属性来告诉派生类上的导航属性应该使用父抽象类中定义的列。我们希望避免使用 DataAnnotations。我只是不明白为什么它会抛出这个错误。 “版本”导航属性是在 AbstractR 配置中定义的,而不是在 SER 配置中定义的(这也应该有效,因为 SER 继承自 AbstractR),对吗?

其次,当删除 Version 属性和映射时,SER 映射中使用的“ChildId”和“ParentId”属性也会出现相同的问题。这是一个已知问题吗?难道我做错了什么 ?

PS:为简单起见,已删除 ParentId 映射,因为它似乎与 ChildId 映射存在相同的问题。

有谁知道为什么会发生这种问题?


UPDATE

经过更多研究后,Fluent API 似乎无法使用基类属性进行映射。是对的吗 ?这是一种想要的行为吗?为什么 DataAnnotations 能够使用基类属性而不是 Fluent API ?不是所有基类属性都插入到每个类中,还是使用某种装饰器模式读取?


只要主体也使用基类类型的导航属性,您就可以使用基类属性作为外键关联。

校长 (Version)已声明ListOfSER作为类型的导航属性SER作为受抚养人

public class Version : BaseObject
{
    public virtual ICollection<SER> ListOfSER { get; set; }
}

,但配置使用基类属性(VersionId) 作为外键关联

public class VersionConfiguration : BaseObjectConfiguration<Version>
{
    public VersionConfiguration()
        : base()
    {
        HasMany(mdv => mdv.ListOfSER)
            .WithRequired()
            .HasForeignKey(ser => ser.VersionId) // -> belongs to base class
            .WillCascadeOnDelete(false);
    }
}

配置时不允许的ForeignKeyConstraintConfiguration,看一下代码摘录

foreach (var dependentProperty in dependentPropertyInfos)
{
    var property
        = dependentEnd.GetEntityType() // -> SER
            .GetDeclaredPrimitiveProperty(dependentProperty); // -> VersionId

    if (property == null) // VersionId is not part of SER metamodel
    {
        throw Error.ForeignKeyPropertyNotFound(
            dependentProperty.Name, dependentEnd.GetEntityType().Name);
    }

    dependentProperties.Add(property);
}

解决方案1将改变ListOfSER输入来自SER into AbstractR.

public class Version : BaseObject
{
    public virtual ICollection<AbstractR> ListOfSER { get; set; }
}

这会更有意义,VersionId是在基类上定义的,任何派生类型都应该能够使用这个外键关联,对吧?但不幸的是Version类型仅允许SER与 相关联Version.

定义 Fluent api 配置时也会出现不一致的情况。

public class VersionConfiguration : BaseObjectConfiguration<Version>
{
    public VersionConfiguration()
        : base()
    {
        HasMany(mdv => mdv.ListOfSER)
            .WithRequired() // -> this should be WithRequired(x => x.Version)
            .HasForeignKey(ser => ser.VersionId)
            .WillCascadeOnDelete(false);
    }
}
public class AbstractRConfiguration : BaseObjectConfiguration<AbstractR>
{
    public AbstractRConfiguration()
        : base()
    {
        HasRequired(ar => ar.Version)
            .WithMany() // -> this should be WithMany(x => x.ListOfSER)
            .HasForeignKey(ar => ar.VersionId)
            .WillCascadeOnDelete(false);
    }
}

更重要的是,您不必在两侧进行配置。只需将其放在VersionConfiguration or AbstractRConfiguration就足够了。

解决方案2将移动Version and VersionId从基类到SER, 如果你想Version只与SER.

public class Version : BaseObject
{
    public virtual ICollection<SER> ListOfSER { get; set; }
}
public abstract class AbstractR : BaseObject
{
}
public class SER : AbstractR
{
    public int VersionId { get; set; }
    public virtual Version Version { get; set; }
}

并配置Version配置或SER配置。

public class VersionConfiguration : BaseObjectConfiguration<Version>
{
    public VersionConfiguration()
        : base()
    {
        HasMany(mdv => mdv.ListOfSER)
            .WithRequired(x => x.Version)
            .HasForeignKey(ser => ser.VersionId)
            .WillCascadeOnDelete(false);
    }
}
public class SERConfiguration : BaseObjectConfiguration<SER>
{
    public SERConfiguration()
        : base()
    {
        HasRequired(ar => ar.Version)
            .WithMany(x => x.ListOfSER)
            .HasForeignKey(ar => ar.VersionId)
            .WillCascadeOnDelete(false);
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

实体框架 Fluent API 不考虑基类属性 的相关文章

  • 以文化中立的方式将字符串拆分为单词

    我提出了下面的方法 旨在将可变长度的文本拆分为单词数组 以进行进一步的全文索引处理 删除停止词 然后进行词干分析 结果似乎不错 但我想听听关于这种实现对于不同语言的文本的可靠性的意见 您会建议使用正则表达式来代替吗 请注意 我选择不使用 S
  • 动态加载程序集的应用程序配置

    我正在尝试将模块动态加载到我的应用程序中 但我想为每个模块指定单独的 app config 文件 假设我的主应用程序有以下 app config 设置
  • 在哪里可以找到列出 SSE 内在函数操作的官方参考资料?

    是否有官方参考列出了 GCC 的 SSE 内部函数的操作 即 头文件中的函数 除了 Intel 的 vol 2 PDF 手册外 还有一个在线内在指南 https www intel com content www us en docs in
  • 嵌套接口:将 IDictionary> 转换为 IDictionary>?

    我认为投射一个相当简单IDictionary
  • 如何使用 ICU 解析汉字数字字符?

    我正在编写一个使用 ICU 来解析由汉字数字字符组成的 Unicode 字符串的函数 并希望返回该字符串的整数值 五 gt 5 三十一 gt 31 五千九百七十二 gt 5972 我将区域设置设置为 Locale getJapan 并使用
  • 用于登录 .NET 的堆栈跟踪

    我编写了一个 logger exceptionfactory 模块 它使用 System Diagnostics StackTrace 从调用方法及其声明类型中获取属性 但我注意到 如果我在 Visual Studio 之外以发布模式运行代
  • 在 Windows 窗体中保存带有 Alpha 通道的单色位图会保存不同(错误)的颜色

    在 C NET 2 0 Windows 窗体 Visual Studio Express 2010 中 我保存由相同颜色组成的图像 Bitmap bitmap new Bitmap width height PixelFormat Form
  • 将 VSIX 功能添加到 C# 类库

    我有一个现有的单文件生成器 位于 C 类库中 如何将 VSIX 项目级功能添加到此项目 最终目标是编译我的类库项目并获得 VSIX 我实际上是在回答我自己的问题 这与Visual Studio 2017 中的单文件生成器更改 https s
  • 使用 WebClient 时出现 System.Net.WebException:无法创建 SSL/TLS 安全通道

    当我执行以下代码时 System Net ServicePointManager ServerCertificateValidationCallback sender certificate chain errors gt return t
  • C#中如何移动PictureBox?

    我已经使用此代码来移动图片框pictureBox MouseMove event pictureBox Location new System Drawing Point e Location 但是当我尝试执行时 图片框闪烁并且无法识别确切
  • C++ OpenSSL 导出私钥

    到目前为止 我成功地使用了 SSL 但遇到了令人困惑的障碍 我生成了 RSA 密钥对 之前使用 PEM write bio RSAPrivateKey 来导出它们 然而 手册页声称该格式已经过时 实际上它看起来与通常的 PEM 格式不同 相
  • 重载<<的返回值

    include
  • WCF 中 SOAP 消息的数字签名

    我在 4 0 中有一个 WCF 服务 我需要向 SOAP 响应添加数字签名 我不太确定实际上应该如何完成 我相信响应应该类似于下面的链接中显示的内容 https spaces internet2 edu display ISWG Signe
  • 如何在整个 ASP .NET MVC 应用程序中需要授权

    我创建的应用程序中 除了启用登录的操作之外的每个操作都应该超出未登录用户的限制 我应该添加 Authorize 每个班级标题前的注释 像这儿 namespace WebApplication2 Controllers Authorize p
  • 如何在 C 中调用采用匿名结构的函数?

    如何在 C 中调用采用匿名结构的函数 比如这个函数 void func struct int x p printf i n p x 当提供原型的函数声明在范围内时 调用该函数的参数必须具有与原型中声明的类型兼容的类型 其中 兼容 具有标准定
  • 如何序列化/反序列化自定义数据集

    我有一个 winforms 应用程序 它使用强类型的自定义数据集来保存数据进行处理 它由数据库中的数据填充 我有一个用户控件 它接受任何自定义数据集并在数据网格中显示内容 这用于测试和调试 为了使控件可重用 我将自定义数据集视为普通的 Sy
  • 使用 x509 证书签署 json 文档或字符串

    如何使用 x509 证书签署 json 文档或字符串 public static void fund string filePath C Users VIKAS Desktop Data xml Read the file XmlDocum
  • cmake 将标头包含到每个源文件中

    其实我有一个简单的问题 但找不到答案 也许你可以给我指一个副本 所以 问题是 是否可以告诉 cmake 指示编译器在每个源文件的开头自动包含一些头文件 这样就不需要放置 include foo h 了 谢谢 CMake 没有针对此特定用例的
  • C# 成员变量继承

    我对 C 有点陌生 但我在编程方面有相当广泛的背景 我想做的事情 为游戏定义不同的 MapTiles 我已经像这样定义了 MapTile 基类 public class MapTile public Texture2D texture pu
  • 如何防止用户控件表单在 C# 中处理键盘输入(箭头键)

    我的用户控件包含其他可以选择的控件 我想实现使用箭头键导航子控件的方法 问题是家长控制拦截箭头键并使用它来滚动其视图什么是我想避免的事情 我想自己解决控制内容的导航问题 我如何控制由箭头键引起的标准行为 提前致谢 MTH 这通常是通过重写

随机推荐

  • 如何在 Swift 中从自定义编码/解码的 json 中删除数据模型 nil 字段

    我正在尝试找到一种干净的方法来删除数据模型可选属性 如果它 nil当在 Swift 中自定义编码 解码我的数据模型时 我的用例 import Foundation public struct Message public let txnID
  • 如何从 PIG 中生成的包(其大小可能会有所不同)中提取第一个元组?

    我正在生成一个信息 包 其大小 包内元组的数量 可能会有所不同 由此 我想动态提取第一个元素 我该怎么做呢 使用DataFu UDF FirstTupleFromBag http datafu incubator apache org do
  • C++ 精度:字符串到双精度

    在对转换为双精度的字符串执行一些操作后 我遇到了双精度的精度问题 include
  • 访问 GridPane 节点时出现问题

    我希望你能帮助我做一个我想做的小项目 我正在尝试使用 JavaFX 的 GUI 创建视频游戏 但遇到了一些麻烦 这是我为练习而编写的代码 我不知道为什么这不起作用 public class Main extends Application
  • 预览期间找不到基于上传文件创建的 StreamedContent

    我在 jsf 页面上创建了一个文件上传对话框和一个图像库 每次上传图像后 图库应显示迄今为止上传的所有图像 图像将存储在后端 bean 中 并且应该由图库从后端 bean 动态获取 由于某种原因 图库显示上传的图像标签 但不显示引用图像 因
  • 选择每个类别的前 10 条记录

    我想在一个查询中返回每个部分的前 10 条记录 任何人都可以帮助如何做到这一点吗 部分是表中的列之一 数据库是 SQL Server 2005 我想返回按输入日期排列的前 10 名 部分分为业务部分 本地部分和特色部分 对于某个特定日期 我
  • codeigniter CSRF 错误:“不允许您请求的操作。”

    我在 codeigniter 的配置文件中启用了 csrf protection 选项 并使用 form open 函数来创建我的表单 但是当我提交表单时 出现以下错误 不允许您请求的操作 我已经完成了类似这个主题的答案 与我的问题最相关
  • Pandas 列中所有字数的总和

    我有一个包含字符串的 pandas 列 我想获得整列中所有单词的字数 在不循环每个值的情况下执行此操作的最佳方法是什么 df pd DataFrame a some words lots more words hi 当运行于df a 你应该
  • 使用 Java 创建具有相似名称的文件而不覆盖现有文件

    我想知道是否可以创建多个具有相似名称的文件 而不覆盖当前文件 例如 如果我有一个文件 xyz txt 下次我创建它时应该是 xyz 1 txt try File makefile new File output txt FileWriter
  • c11 _Generic 泛型关联的结果表达式的每个分支都必须有效吗?

    我似乎无法将参数传递给需要不同参数的函数 或传递给实现第一个类型的子集的其他 Generic 宏 define DEBUG PRINT x Generic x debug print options DEBUG PRINT CUSTOM T
  • ORACLE NLS_LANG

    如何设置和检查NLS LANG设置 我做到了 set NLS LANG DANISH DENMARK WE8ISO8859P2 在命令提示符下 但我不知道它是否正确 这取决于操作系统和命令解释器 Linux bash echo NLS LA
  • CSS:根据其 href 设置链接样式

    我的网站上有一个我想要设置样式的第三方链接 但它没有任何我可以定位的类或 ID 它唯一拥有的就是它独特的 href 值 是否可以根据其 href 值设置锚标记的样式 您可以使用 href css 选择器来设置样式a基于链接的标签 a hre
  • 如何使用 Python 获取 SVG 路径的高度、宽度和长度?

    我有一个 svg 其中有大量这样的路径
  • FCM 字段“数据”必须是 JSON 数组

    您好 我正在与邮差一起制作我的 json 对象 FCM 消息 但是当我尝试发送时 to fzvihT7dFUI APA91bFVhnWAxXVjlWiiHIs9ZUyL1DE2hZO6GpItJtReh3hcKF1kD6mLuQq9fNP9
  • repz ret:为什么这么麻烦?

    的问题repz ret已经在这里介绍了 1 以及其他来源 2 3 还算满意 然而 在阅读这两个来源时 我找到了以下问题的答案 是什么actual定量比较中的惩罚ret or nop ret 尤其是在后一种情况下 当大多数函数要么有 100
  • 应用程序兼容主题的弹出菜单分隔线

    我使用了应用程序兼容主题样式
  • 在同一行上获取 2 个 div

    我试图让 2 个 div 位于同一行 我已经 div class header div class clear hideSkiplink div class menuDiv div div div
  • 创建带有滚动条的下拉列表

    我有一个包含选项列表的 HTML 下拉列表 当用户单击下拉列表时 应该会看到带有滚动条的前五个选项 我想使用 JavaScript 和 CSS 来实现这一点 由于我对这些不熟悉 请建议我如何使用滚动条显示下拉列表 以便能够滚动并从下拉列表中
  • RegOpenKeyEx() 错误

    我正在使用 Qt 和 mingw 来编写一个更改注册表的程序 但是当我调用时 RegOpenKeyEx HKEY LOCAL MACHINE SOFTWARE Microsoft Windows NT CurrentVersion Defa
  • 实体框架 Fluent API 不考虑基类属性

    EF 6 1 我们刚刚启动了一个有很多继承的项目 选定的继承数据库映射类型是每个层次结构的表 问题是 当尝试使用 add migration 生成迁移时 会引发以下错误 The foreign key component VersionId