将导航属性映射到实例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.RecipientGroupId
的FOREIGN 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()
调用将其映射)或者集合导航属性,然后在业务逻辑中确保此集合不能包含多个元素。