gpt4 book ai didi

c# - Entity Framework : Composite Foreign Key on unique (not primary keys) parent fields

转载 作者:太空宇宙 更新时间:2023-11-03 10:50:31 26 4
gpt4 key购买 nike

我有一个表需要通过其 Id 列绑定(bind)到另一个表,并通过其 (Id, Code) 列绑定(bind)到第三个表。我可以使用主键和唯一索引在 SQL Server 中轻松执行操作,但不知道如何在 Entity Framework 中实现它。

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

否则,如果我只应用一个[Key],那么我无法建立第二个关系。

有解决办法吗?

最佳答案

好的,我能够使用 Fluent API 创建所需数量的 key 。现在可以了。

更详细:
在业务术语中,我有一个 Form 对象,它具有与 html 文档中一样的字段 - 类型为 input、choice、text、radiogroup 等。
我更喜欢将强类型的字段数据存储在单独的表中,但表单需要知道哪些字段位于其中以维护它们的唯一顺序。

所以在数据库中我有表:

Form - 包含 Form 的名称和描述
FormField -(每个表单 0 到许多行)包含 FormIdFieldTypeOrderNo。通过将 (FormId, OrderNo) 设置为唯一,我保持了正确的顺序。

诀窍是类型字段本身存储在不同的表中,如 InputFieldChoiceFieldNumberField 等。我希望它们是绑定(bind)到父 FormField 行,例如 0 或 1 到 1,并且在删除父行时不允许它们丢失。
如果它是简单的父子关系,我可以使用标准 FK,但这里我有 variuos 子表。

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

所以,我的问题是让 ChoiceField 表有两组键:一组是复合键,用于父 FieldForm 行,第二组是简单键 - 用于 ChoiceOption 子表。
使用 Fluent API,我能够添加第二个 key 。

这是我的 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>();
// ...
}

关于c# - Entity Framework : Composite Foreign Key on unique (not primary keys) parent fields,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21579516/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com