Entity Framework 4.1 Code First,一对一,一个表连接到复合键的单个键字段
Posted
技术标签:
【中文标题】Entity Framework 4.1 Code First,一对一,一个表连接到复合键的单个键字段【英文标题】:Entity Framework 4.1 Code First, One-to-One with one table joining to a single key field of of composite key 【发布时间】:2011-07-22 12:39:23 【问题描述】:我刚刚开始使用 EF4.1 Code First,我非常喜欢它。
故事是这样的: Codif 类由来自 Domaine 类、Entite 类和 Reference 类的键和第四个字段组成,该字段是一些文本。 Reference 和 Codif 是一对一的关系。
事情是,当它创建数据库时,它会在我的参考实体中创建一些丑陋的字段,创建 Codif 实体的重复字段。 好点:但是,当我操作我的 Reference 对象时,我有访问 Codif 属性的预期行为,并且重复的字段是不可见的。
代码如下:
public class Reference
public int ReferenceId get; set;
public string Libelle get; set;
public virtual Codif Codif get; set;
public class Domaine
public int DomaineId get; set;
public string Libelle get; set;
public class Codif
[Key, Column(Order = 0)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int DomaineId get; set;
[InverseProperty("DomaineId")]
public virtual Domaine Domaine get; set;
[Key, Column(Order = 1)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int EntiteId get; set;
[InverseProperty("EntiteId")]
public virtual Entite Entite get; set;
[Key, Column(Order = 2)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ReferenceId get; set;
[InverseProperty("ReferenceId")]
public virtual Reference Reference get; set;
[Key, Column(Order = 3)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public string Codification get; set;
public class Entite
public int EntiteId get; set;
public string Nom get; set;
public string Email get; set;
这是表格中的结果(图片):
Codif
Reference
-
在 Reference 类中,如何指定 ReferenceId 是用于 Codif 的 SINGLE 字段的外键?
如何去除 Reference 中的重复字段?
如何在保留导航属性的同时删除 Codif 表中的 Reference_ReferenceId ?
感谢您的支持。
马克
编辑:我正在使用 SQL Compact Edition 4 数据库
【问题讨论】:
【参考方案1】:将所有[InverseProperty("xxx")]
属性替换为[ForeignKey("xxx")]
。我认为这就是你真正想要的。 [InverseProperty]
指的是关系另一端的导航属性,它永远不能是标量属性。
编辑
除了 FK 属性外,您还可以在 Codif
类中的 Reference
属性上设置 [InverseProperty]
属性:
public class Codif
//...
[Key, Column(Order = 2)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ReferenceId get; set;
[ForeignKey("ReferenceId")]
[InverseProperty("Codif")] // <-- refers to Codif property in Reference class
public virtual Reference Reference get; set;
//...
但它认为这并不是真正必要的,因为 EF 应该按照约定检测 Reference
和 Codif
之间的正确关系。 (我不确定一对一的关系。)
编辑
问题!
首先:据我所知,您必须在 Fluent API 中指定一对一的关系,因为 EF 无法确定什么是主体,什么是依赖:
modelBuilder.Entity<Reference>()
.HasOptional(c => c.Codif)
.WithRequired(c => c.Reference);
第二:EF 仍然会因为组合键或者ReferenceId
不是唯一的键而抱怨。如果ReferenceId
是Codif
中的唯一键,它将起作用。
编辑
我正在尝试了解您想要实现的目标。显然,Codif
中的组合键应该确保四个字段值的任何组合只能存在一次。但这与 imo 的一对一关系冲突,例如这将是有效的表条目:
Table Codif:
DomaineId EntiteId ReferenceId Codification
----------------------------------------------------
1 1 1 "A"
2 1 1 "A"
1 2 1 "A"
1 1 2 "A"
1 1 1 "B"
etc...
但如您所见:您可以有多个具有相同ReferenceId
的行,这意味着您不能与Reference
建立一对一的关系。这里有 4 个 Codif
实体,它们引用同一个 ID = 1 的 Reference
实体。
现在,我想,您希望建立一对一关系这一事实意味着存在一个额外的约束,以便Codif
表中的ReferenceId
只能出现一次。换句话说:上面示例中的第 2、3 和 5 行从业务角度来看是无效的(尽管从 DB 角度来看是有效的)。
如果是这种情况,我实际上会将ReferenceId
设为Codif
中的单个键,并从业务逻辑确保数据库中的其他值组合是唯一的(在插入新的@987654344 之前查询是否存在@)。在数据库方面,您可以在其他三个字段上创建唯一索引,以确保组合在数据库中始终是唯一的。 EF 无法在内部对此进行检查,因为尚不支持唯一约束。
【讨论】:
以上是关于Entity Framework 4.1 Code First,一对一,一个表连接到复合键的单个键字段的主要内容,如果未能解决你的问题,请参考以下文章
Entity Framework 4.1Code First 连接到 Sql Server 2005
Entity Framework 4.1 Code First 关系中的更改通常不需要
Entity Framework 4.1 Code First - 插入非主键时自动递增字段
我应该如何在 MVC3 中使用 Code First Entity Framework (4.1) 声明外键关系?