将导航属性映射到实例var作为外键

我正在使用.Net Framework 4.0开发一个entity framework代码优先(v.4.4.0.0)C#库。

我不知道如何建立零对一的关系。 我的模型如下:

只能由一个用户( StarterUserId )创建Talk
Talk只能有一个收件人用户( RecepientUserId )或只有一个组( RecipientGroupId )。
注意 :这意味着如果RecipientGroupId不为null,则RecipientGroupId为null; 如果RecipientGroupId为null,则RecepientUserId不为null。

user可以是零或n个Talks的接收者,但是一个group可以有零个或一个Talk

这是Talk课程:

 [DataContract] public class Talk { [DataMember] public int TalkId { get; set; } [DataMember] public int StarterUserId { get; set; } [DataMember] public int? RecipientUserId { get; set; } [DataMember] [ForeignKey("RecipientGroup")] public int? RecipientGroupId { get; set; } public DateTime DateUtcStarted { get; set; } [DataMember] public string DateStarted { get { return DateUtcStarted.ToString("dd/MM/yyyy HH:mm"); } set { DateUtcStarted = DateTime.Parse(value); } } public User StarterUser { get; set; } public User RecipientUser { get; set; } public Group RecipientGroup { get; set; } } 

使用此TalkConfiguration类:

 class TalkConfiguration : EntityTypeConfiguration { public TalkConfiguration() { Property(t => t.StarterUserId).IsRequired(); Property(t => t.RecipientUserId).IsOptional(); Property(t => t.RecipientGroupId).IsOptional(); Property(t => t.DateUtcStarted).IsRequired(); Ignore(t => t.DateStarted); HasRequired(t => t.StarterUser). WithMany(u => u.TalksStarted). HasForeignKey(t => t.StarterUserId); HasOptional(t => t.RecipientUser). WithMany(u => u.InTalks). HasForeignKey(t => t.RecipientUserId); HasOptional(t => t.RecipientGroup).WithOptionalDependent(g => g.GroupTalk); } } 

这是Group类:

 [DataContract] public class Group { [DataMember] public int GroupId { get; set; } [ ... ] public Talk GroupTalk { get; set; } } 

GroupConfiguration类:

 class GroupConfiguration : EntityTypeConfiguration { public GroupConfiguration() { [ ... ] // Nothing related to GroupTalk } } 

通过这些类和配置,我在数据库中获得了这个Talk表:

在此处输入图像描述

我想将Talk.RecipientGroupId作为Talk.RecipientGroupIdFOREIGN KEY 。 但是这个模型创建了另一个列, Talk.RecipientGroup_GroupId作为Talk.RecipientGroup_GroupId FOREIGN KEY 。 而且,我不希望这样。

我该怎么做?

可选:可选的一对一关系映射为独立关联,而不是外键关联,这意味着您的模型类中不能具有外键属性。 这就是为什么你不能在HasForeignKey之后WithOptionalDependent 。 我很确定RecipientGroupId上的[ForeignKey]属性被简单地忽略,EF认为RecipientGroupId是一个没有关系目的的普通标量属性。

在数据库模式本身中,该关系具有外键。 这是您使用自动生成的默认名称所看到的那个: RecipientGroup_GroupId 。 但是不支持将此外键映射到属性。 但是,我认为您可以使用MapKey重命名该列

 HasOptional(t => t.RecipientGroup) .WithOptionalDependent(g => g.GroupTalk) .Map(m => m.MapKey("RecipientGroupId")); 

如果这样做,则必须Talk类中删除RecipientGroupId属性,否则EF将抱怨具有相同名称的两个冲突列。

我相信,可选:可选是唯一的一对一关系,它们是独立关联,所有其他都是外键关联,其中外键属性同时是主键属性(根据Arthur Vickers在底部的回答) 这个线程 )。 使用可选:可选关系,这是不可能的,因为主键属性不能为空。

由于您的RecipientGroupId具有[DataMember]属性,因此您希望在某些服务边界上传输该值,因此出于某种原因需要外键作为属性值。 在这种情况下,我选择的解决方法是将Talk<->Group关系映射为一对多关系,根本不包含Group类中的导航属性(使用无参数的WithMany()调用将其映射)或者集合导航属性,然后在业务逻辑中确保此集合不能包含多个元素。