实体框架:唯一(非主键)父字段上的复合外键

2024-04-24

我有一个表需要通过其绑定到另一个表Id列,并按其第三个表(Id, Code)列。我可以轻松地做SQL服务器同时使用主键和唯一索引,但不知道如何实现它实体框架.

如果我把[Key]两列上的属性,那么我无法创建第一个关系。

否则,如果我只申请一个[Key]那么我就无法建立第二段关系。

有什么解决方法吗?


好的,我可以使用以下方法制作所需数量的钥匙流畅的API。现在可以了。

更详细:
从商业角度来说,我有一个Form具有字段的对象,就像 html 文档中的类型一样input, choice, text, radiogroup etc.
我更喜欢将强类型的字段数据存储在单独的表中,但表单需要知道哪些字段位于其中以维持其唯一顺序。

所以在数据库中我有表:

Form- 包含表单的名称和描述
FormField-(每个表格 0 到多行)包含FormId, 字段类型 and OrderNo。通过设置(表单 ID、订单号)为了独特,我保持正确的顺序。

诀窍在于类型化字段本身存储在不同的表中,例如InputField, ChoiceField, NumberField我希望它们与父 FormField 行绑定在一起,如 0 或 1 到 1,并且不允许它们在删除父行时丢失。
如果是简单的父子关系,我可以使用标准 FK,但这里我有各种子表。

为了使一切保持一致,在SQL服务器我创建了一个复合PK(表单 ID、字段类型)在父级中FormField表和 FK 为(表单 ID、字段类型)在所有子表中FieldType设置为常数计算值(例如 0InputField表 1 中ChileField表等)。
因此,我对单个对象有一个很好的父子约束FormField和多个子特定类型表。
在 EF 方法中,要制作复合 FK,您需要所有相应字段都是 Key,因此您将 [Key] 属性放在两个字段上。
但是,如果您的特定类型表需要有自己的子表(例如ChoiceField有它的ChoiceOptions),并且您已经有一个复合密钥,那么您需要使用现有的复合密钥或添加一个新的密钥集(仅Id场地)。

因此,我的问题是使 ChoiceField 表具有两组键:一组是复合键,用于父 FieldForm 行,第二组是简单键 - 用于 ChoiceOption 子表。
使用 Fluent API,我可以添加第二个密钥。

这是我的 EF 模型:

[Table("Form")]
public class Form : IEntity
{
    [Key, Column("FormID")]
    public int Id { get; set; }

    [Required, StringLength(50)]
    public string Name { get; set; }

    public ICollection<FormField> FormFields { get; set; }
}

[Table("FormField")]
public class FormField : IEntity
{
    [Key, Column("FormFieldID", Order = 0)]
    public int Id { get; set; }

    [Key, Column(Order = 1)]
    public FieldType FieldType { get; set; }

    [ForeignKey("Form")]
    public int FormId { get; set; }

    public int OrderNo { get; set; }

    public virtual Form Form { get; set; }

    public virtual AddressField AddressField { get; set; }
    public virtual ChoiceField ChoiceField { get; set; }
    public virtual DateTimeField DateTimeField { get; set; }
// etc
}

[Table("ChoiceField")]
public class ChoiceField : BaseField, IEntity
{
    [Key, ForeignKey("FormField"), Column("FormFieldID", Order = 0)] // these keys are for parent FormField table
    public int Id { get; set; }

    [Key, ForeignKey("FormField"), Column(Order = 1)]
    public FieldType FieldType { get; set; }

    public virtual FormField FormField { get; set; }

    public ICollection<ChoiceFieldOption> ChoiceFieldOptions { get; set; }
}

[Table("ChoiceFieldOption")]
public class ChoiceFieldOption : IEntity
{
    [Key, Column("ChoiceFieldOptionID")]
    public int Id { get; set; }

    [ForeignKey("ChoiceField")] // this FK are bound to simple ChoiceField.Id key defined in fluent API
    public int ChoiceFieldId { get; set; }

    [Required, StringLength(50)]
    public string Option { get; set; }

    public int OrderNo { get; set; }

    public virtual ChoiceField ChoiceField { get; set; }
}

...

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {

        modelBuilder.Entity<Form>();
        var eFormField = modelBuilder.Entity<FormField>();

        var eChoiceField = modelBuilder.Entity<ChoiceField>();

    // here I add a second Key for ChoiceField table
        eChoiceField.HasKey(cf => new { cf.Id });

        var eChoiceFieldOption = modelBuilder.Entity<ChoiceFieldOption>();

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

实体框架:唯一(非主键)父字段上的复合外键 的相关文章

  • 如何使用 LINQ 获取唯一 id 列的最大值

    如何使用 LINQ 以最简单的方式编写此代码 SELECT MAX Game id AS MaxValue FROM Dim Game Try context Dim Games Max g gt g Game id
  • 如何在没有 Control.Invoke() 的情况下从后台线程修改控件属性

    最近 我们遇到了一些旧版 WinForms 应用程序 我们需要更新一些新功能 在专家测试该应用程序时 发现一些旧功能被破坏 无效的跨线程操作 现在 在您认为我是新手之前 我确实有一些 Windows 窗体应用程序的经验 我不是专家 但我认为
  • FFMPEG Seeking 带来音频伪影

    我正在使用 ffmpeg 实现音频解码器 在读取音频甚至搜索已经可以工作时 我无法找到一种在搜索后清除缓冲区的方法 因此当应用程序在搜索后立即开始读取音频时 我没有任何工件 avcodec flush buffers似乎对内部缓冲区没有任何
  • fgets() 和 Ctrl+D,三次才能结束?

    I don t understand why I need press Ctrl D for three times to send the EOF In addition if I press Enter then it only too
  • SSH 主机密钥指纹与模式 C# WinSCP 不匹配

    我尝试通过 WinSCP 使用 C 连接到 FTPS 服务器 但收到此错误 SSH 主机密钥指纹 与模式不匹配 经过大量研究 我相信这与密钥的长度有关 当使用 服务器和协议信息 下的界面进行连接时 我从 WinSCP 获得的密钥是xx xx
  • 为什么 POSIX 允许在只读模式下超出现有文件结尾 (fseek) 进行搜索

    为什么寻找文件结尾很有用 为什么 POSIX 让我们像示例中那样在以只读方式打开的文件中进行查找 c http en cppreference com w c io fseek http en cppreference com w c io
  • C# 中值类型和引用类型有什么区别? [复制]

    这个问题在这里已经有答案了 我知道一些差异 值类型存储在堆栈上 而引用类型存储在托管堆上 值类型变量直接包含它们的值 而引用变量仅包含对托管堆上创建的对象位置的引用 我错过了任何其他区别吗 如果是的话 它们是什么 请阅读 堆栈是一个实现细节
  • 写入和读取文本文件 - C# Windows 通用平台应用程序 Windows 10

    有用 但在显示任何内容之前 您必须在文本框中输入内容 我想那是因为我使用了 TextChanged 事件处理程序 如果我希望它在没有用户交互的情况下显示文本文件的内容 我应该使用哪个事件处理程序 因此 我想在按下按钮时将一些数据写入 C W
  • C# 用数组封送结构体

    假设我有一个类似于 public struct MyStruct public float a 我想用一些自定义数组大小实例化一个这样的结构 在本例中假设为 2 然后我将其封送到字节数组中 MyStruct s new MyStruct s
  • HttpClient 像浏览器一样请求

    当我通过 HttpClient 类调用网站 www livescore com 时 我总是收到错误 500 可能服务器阻止了来自 HttpClient 的请求 1 还有其他方法可以从网页获取html吗 2 如何设置标题来获取html内容 当
  • 基于范围的 for 循环中的未命名循环变量?

    有没有什么方法可以不在基于范围的 for 循环中 使用 循环变量 同时也避免编译器发出有关未使用它的警告 对于上下文 我正在尝试执行以下操作 我启用了 将警告视为错误 并且我不想进行像通过在某处毫无意义地提及变量来强制 使用 变量这样的黑客
  • 为什么模板不能位于外部“C”块内?

    这是一个后续问题一个答案 https stackoverflow com questions 4866433 is it possible to typedef a pointer to extern c function type wit
  • 是否有比 lex/flex 更好(更现代)的工具来生成 C++ 分词器?

    我最近将源文件解析添加到现有工具中 该工具从复杂的命令行参数生成输出文件 命令行参数变得如此复杂 以至于我们开始允许它们作为一个文件提供 该文件被解析为一个非常大的命令行 但语法仍然很尴尬 因此我添加了使用更合理的语法解析源文件的功能 我使
  • 将 System.Windows.Forms.Keys 序列转换为 Char

    有没有办法转换由 Keys 枚举表示的击键序列 即System Windows Forms Keys 在一个字符中 例如 Keys Oem4进而Keys A产生 char 它一定存在于 WinAPI 中的某个地方 因为当我在文本框中按下按键
  • 可空属性与可空局部变量

    我对以下行为感到困惑Nullable types class TestClass public int value 0 TestClass test new TestClass Now Nullable GetUnderlyingType
  • 检查 url 是否指向文件或页面

    我们需要以下内容 如果文件确实是文件 则从 URL 下载该文件 否则 如果它是一个页面 则什么也不做 举个简单的例子 我有以下命令来下载文件 My Computer Network DownloadFile http www wired c
  • 在 URL 中发送之前对特殊字符进行百分比编码

    我需要传递特殊字符 如 等 Facebook Twitter 和此类社交网站的 URL 为此 我将这些字符替换为 URL 转义码 return valToEncode Replace 21 Replace 23 Replace 24 Rep
  • char指针或char变量的默认值是什么[重复]

    这个问题在这里已经有答案了 下面是我尝试打印 char 变量和指针的默认值 值的代码 但无法在控制台上看到它 它是否有默认值或只是无法读取 ASCII 范围 include
  • 如何构建印度尼西亚电话号码正则表达式

    这些是一些印度尼西亚的电话号码 08xxxxxxxxx 至少包含 11 个字符长度 08xxxxxxxxxxx 始终以 08 开头 我发现这个很有用 Regex regex new Regex 08 0 9 0 9 0 9 0 9 0 9
  • 窗体最大化时自动缩放子控件

    有没有办法在最大化屏幕或更改分辨率时使 Windows 窗体上的所有内容自动缩放 我发现手动缩放它是正确的 但是当切换分辨率时我每次都必须更改它 this AutoScaleDimensions new System Drawing Siz

随机推荐

  • java.util.Properties 字段的 Spring JavaConfig

    您能告诉我如何使用 Spring Javaconfig 直接将属性文件加载 自动装配到 java util Properties 字段吗 Thanks 稍后编辑 仍在寻找答案 是否可以使用 Spring JavaConfig 将属性文件直接
  • PHPMailer 和 Gmail 对话视图

    当我们的服务器收到更新 通常与付款相关 时 我使用 PHPMailer 发送电子邮件以提供支持 我正在尝试将相关电子邮件显示为 Gmail 对话 以便支持人员更轻松地跟踪之前的更新 回复 我最初认为它是基于主题的 但这似乎没有什么区别 我的
  • 使用 setTimeout 和 Jest 测试 Promise

    我试图理解 Jest 的异步测试 我的模块有一个函数 它接受布尔值并返回值的 Promise 执行器函数调用setTimeout 并且在超时回调中 promise 会根据最初提供的布尔值进行解析或拒绝 代码如下所示 const withPr
  • 当应用程序在后台时使用 uni_links

    我的应用程序具有以下结构 InheritedWidget for dependencies gt Splash Screen Page gt Login Pages gt Main Pages 当应用程序第一次运行时 我可以使用var li
  • 使用流浪文件回答提示?

    是否可以将脚本添加到 Vagrantfile 来回答提示 我正在为 docker 配置一个 ubuntu 盒子 config vm box ubuntu config vm provision shell inline gt sudo ap
  • 更改浏览器选项卡会意外触发焦点事件,尤其是在 Google Chrome 中

    我刚刚意识到焦点事件有一个小问题 显然 当切换到另一个浏览器选项卡然后再次返回时 焦点会被触发 我宁愿不要这样的事情发生 是否可以 直到今天我才意识到这一点 这是一个小演示 http jsfiddle net MJ6qb 1 http js
  • XmlReader AppendChild 未附加相同的子值

    XmlElement updateRecipient doc CreateElement UpdateRecipient XmlElement email doc CreateElement EMAIL XmlElement listID
  • 是否有适用于 IE6 的 JavaScript PNG 修复程序允许 CSS 背景定位?

    我已经看到了一些允许 PNG 图像在 Internet Explorer 6 中具有透明度的修复 但我还没有找到一个也允许您在 CSS 中设置背景位置的修复 如果你使用精灵 那就会破坏交易 我求助于使用 GIF 质量不高 根本不使用透明图像
  • Django QuerySet 何时被评估?

    我读过 django 查询集是懒惰的 但这是否意味着懒惰 因为我可以在一个语句上链接多个操作 或者懒惰 因为查询被延迟到需要结果的时候 例如 以下模拟代码是否执行两个或三个 SQL 查询 query Books objects filter
  • StreamWriter.Flush() 和 StreamWriter.Close() 有什么区别?

    两者在功能上有什么区别StreamWriter Flush and StreamWriter Close 当我的数据没有正确写入文件时 我添加了两个Flush and Close 到我的代码的末尾 然而 我意识到添加either Flush
  • 具有来自包含器类的静态方法调用的 Ruby 模块

    我需要在模块中定义使用包含该模块的类中的方法的常量 module B def self included base class lt lt base CONST self find end end end class A def self
  • 如何确保以编程方式发送的电子邮件不会被自动标记为垃圾邮件?

    这是一个棘手的问题 我一直依赖技术 例如基于许可的电子邮件 即仅发送给您有权发送的人 而不是公然使用spamish术语 最近 我以编程方式发送的一些电子邮件开始被自动混入人们的垃圾邮件文件夹中 我想知道我能对此做些什么 尽管这些特定的电子邮
  • 为什么空 python 正则表达式搜索的返回值是匹配的?

    将空字符串传递给正则表达式对象时 搜索结果是匹配对象而不是 None 因为没有任何东西可以匹配 所以它应该是 None 吗 import re m re search some text if m is None print Returne
  • 从新线程更新 JProgressBar

    如何从另一个线程更新 JProgressBar setValue int 我的第二个目标是用尽可能少的课程来完成它 这是我现在的代码 Part of the main class pp addActionListener new Actio
  • 在 F# 中组合谓词

    F 中是否有逻辑组合谓词的标准方法 例如 假设我有isCar x and isBlue x然后我想要一些能给我的东西 let isBlueCar x isCar x isBlue x 但是使用某种组合而不是调用 可能像 let isBlue
  • 扫描大量BLE标签

    我一直在寻找在一次扫描中扫描大量 BLE 标签 StickNFind 的可能性 我注意到 当我扫描 10 秒时 我可以轻松检测到大约 20 个 BLE 当我将扫描间隔增加到 30 秒左右并尝试扫描大量 BLE 标签时 例如200 个标签 我
  • WPF:无法控制键盘焦点

    这周我遇到了一个让我陷入困境的问题 总而言之 问题是当我左键单击另一个控件时 我无法从代码中将键盘焦点赋予 ComboBox 具体来说 我有一个 CustomControll 它有一个 Scrollview 其中包含另一个 CustomCo
  • 与使用类相比,在 Program.cs/main 中编写代码是否有充分的理由? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我正在开发一个相当大的应用程序 而我的技术主管和我在某些事情上的看法并不一致 其中之一是关于控制台应用程序 这些应用程序正在从 shell 脚本移植到
  • 无法在我的 Maven 项目中使用依赖项 jboss-javaee-6.0

    我已经使用 JBoss 7 1 1 设置了一个 Maven 项目 我想使用 JavaEE 库 在根 pom xml 中我设置了
  • 实体框架:唯一(非主键)父字段上的复合外键

    我有一个表需要通过其绑定到另一个表Id列 并按其第三个表 Id Code 列 我可以轻松地做SQL服务器同时使用主键和唯一索引 但不知道如何实现它实体框架 如果我把 Key 两列上的属性 那么我无法创建第一个关系 否则 如果我只申请一个 K