Jen*_*112 29 c# database entity-framework ef-code-first entity-framework-6
我正在尝试执行以下操作:
public class class1
{
public int Id {get;set;}
[ForeignKey("Class2")]
public int Class2Id {get;set;}
public virtual Class2 Class2 {get;set;}
}
public class class2
{
public int Id { get; set;}
[Required]
public virtual int Class1Id {get;set;}
[Required]
[ForeignKey("Class1Id")]
public Class1 Class1 {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
但是,每次我尝试迁移我的数据库时,都会收到以下错误:
Class1_Class2_Target :: Multiplicity在关系'Class2_Class1'中的角色'Class2_Class1_Target'中无效.由于"从属角色"属性不是关键属性,因此从属角色的多重性的上限必须为"*".
这可能是什么问题?
Ger*_*old 60
您的模型不是1:1关联.您仍然可以有许多 Class2对象引用同一个 Class1对象.此外,您的模型不保证Class2引用a Class1也被此Class1对象Class1引用- 可以引用任何Class2对象.
在SQL中保证(排序)1:1关联的常用方法是为主体提供一个表,为依赖实体设置一个表,其中从属表中的主键也是主体的外键:

(这Class1是委托人)
现在在关系数据库中,这仍然不能保证1:1关联(这就是为什么我说'有点').这是一个1:0..1的关联.可以有一个Class1没有Class2.事实是,在SQL中不可能实现真正的1:1关联,因为没有语言结构可以同步在不同的表中插入两行.1:0..1是我们最接近的.
流畅的映射
要在EF中建模此关联,您可以使用流畅的API.这是执行此操作的标准方法:
class Class1Map : EntityTypeConfiguration<Class1>
{
public Class1Map()
{
this.HasKey(c => c.Id);
this.Property(c => c.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
this.HasRequired(c1 => c1.Class2).WithRequiredPrincipal(c2 => c2.Class1);
}
}
Run Code Online (Sandbox Code Playgroud)
在上下文中:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new Class1Map());
}
Run Code Online (Sandbox Code Playgroud)
这是你的课程:
public class Class1
{
public int Id {get;set;}
public virtual Class2 Class2 {get;set;}
}
public class Class2
{
public int Id {get;set;}
public virtual Class1 Class1 {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
无法在模型中配置备用外键属性,因为所涉及的唯一FK 必须是从属主键.
关于这个模型的奇怪之处在于EF不会阻止你创建(并保存)一个没有的class1对象.我认为EF应该能够在保存更改之前验证此要求,但显然,它没有.同样,有一些方法可以删除对象而不删除其父对象.所以这对- 并不像它看起来那么严格(应该是).class2class2class1HasRequiredWithRequired
数据注释
在代码中实现此功能的唯一方法是通过数据注释.(当然数据库模型仍然无法以1:1强制执行)
public class Class1
{
public int Id {get;set;}
[Required]
public virtual Class2 Class2 {get;set;}
}
public class Class2
{
[Key, ForeignKey("Class1")]
public int Id {get;set;}
[Required]
public virtual Class1 Class1 {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
该[Key, ForeignKey("Class1")]注解告诉EF这Class1是主要实体.
数据注释在许多API中扮演着一个角色,这可能是一个诅咒,因为每个API都选择自己的子集来实现,但这里派上用场,因为现在EF不仅使用它们来设计数据模型,还用于验证实体.现在,如果您尝试保存class1对象而不会class2出现验证错误.
Riz*_*zJa -1
两个类之一必须在另一个类之前创建,因此需要 [Required] 注释。如果 Class2 依赖于 Class1,则指定 [Required,foreignKey("Class1")]。您还可以使用 Fluent API 在上下文类中进行配置。
| 归档时间: |
|
| 查看次数: |
42706 次 |
| 最近记录: |