我刚开始使用EF4.1 Code First,我非常喜欢它。
这是故事: Codif类由Domaine类中的键,Entite类和Reference类组成,第四个字段是一些文本。 Reference和Codif有一对一的关系。
事情是,当它创建数据库时,它会在我的Reference实体中创建一些丑陋的字段,从而创建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; }
}
这是表格(图片)中的结果:
感谢您的支持。
马克
编辑:我正在使用SQL Compact Edition 4数据库
答案 0 :(得分:0)
将所有[InverseProperty("xxx")]
属性替换为[ForeignKey("xxx")]
。我认为这就是你真正想要的。 [InverseProperty]
指的是关系另一边的导航属性,它永远不会是标量属性。
修改强>
除了FK属性之外,您还可以在[InverseProperty]
类的Reference
属性中设置Codif
属性:
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);
第二:由于组合密钥或因ReferenceId
不是单独的密钥,EF仍然会抱怨。如果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
实体。
现在,我想,您希望拥有一对一关系这一事实意味着存在一个额外的约束,以便ReferenceId
表中的Codif
只能出现一次。换句话说:上述示例中的第2,3和5行在业务视点中无效(尽管从DB视点有效)。
如果是这种情况,我实际上将ReferenceId
作为Codif
中的单个密钥,并从业务逻辑确保数据库中其他值组合是唯一的(在插入之前存在查询)一个新的Codif
)。在数据库端,您可以在其他三个字段上创建唯一索引,以确保组合在数据库中始终是唯一的。 EF无法在内部检查,因为尚不支持唯一约束。