我有以下POCO对象:
public class Chat
{
public int ChatID { get; set; }
public virtual Audio ChatAudio { get; set; }
public virtual Video ChatVideo { get; set; }
}
public class Audio
{
public int AudioID { get; set; }
public int ChatID { get; set; }
public Chat Chat { get; set; }
public DateTime Recorded { get; set; }
}
public class Video
{
public int VideoID { get; set; }
public int ChatID { get; set; }
public Chat Chat { get; set; }
public DateTime Recorded { get; set; }
}DBA设置了以下表
-Chat-
ChatID
-Audio-
AudioID
ChatID <-- FK, Unique Index
Recorded
-Video-
VideoID
ChatID <-- FK, Unique Index
Recorded所以这是一个1对可选的关系。他不想在Chat表上为Audio或Video创建一个可以为空的列。如何在EF代码中强制执行此操作?我让它工作的唯一方法是创建那些导航属性集合和定义的HasMany()。我不想那样做。我希望能够做到:
if(Chat.Audio == null || Chat.Video==null)
{
// Do stuff
}我很感谢你的任何建议。
发布于 2011-12-13 07:07:04
不能,您不能使用Entity Framework将此模型映射到您的数据库架构(无论是哪个版本到当前版本4.2)。
主要原因是EF不支持唯一键约束,这意味着:将引用导航属性映射到数据库中具有唯一键约束的列。EF会认为数据库中这样的FK列始终不是唯一的,并且看不到唯一键约束。因此,Chat中两个关联的结尾必须是集合。或者你不能在你的模型中公开它们,但是在内部EF会一直认为它们是“许多”-ends。
EF支持的唯一真正的一对一关系是共享主键关系。这意味着在Audio和Video表中没有ChatId列,而是主键列AudioId和VideoId同时是Chat表的外键列。显然,主键列不可能是数据库中所有自动生成的标识,从而使这种映射成为可能。
在这里可以找到对一对一映射策略的很好的描述以及它们的优点和限制的比较:
发布于 2011-12-14 02:17:07
您可以“作弊”并将关系配置为一对多,在对象模型中强制执行一对一(此外,在datacontext初始化器中,您可以手动向数据库添加唯一约束)。
它基本上看起来像这样
public class Chat
{
public int ChatID { get; set; }
protected virtual ICollection<Audio> HiddenAudioCollection{get;set;}
public Audio ChatAudio
{
get{return HiddenAudioCollection.FirstOrDefault();}
set
{
if(HiddenAudioCollection==null)
HiddenAudioCollection=new List<Audio>();
if(HiddenAudioCollection.Any())
{
//decide if you throw an exception or delete the existing Audio
}
HiddenAudioCollection.Add(value);
}
}
//Do the same with ChatVideo
} 发布于 2011-12-14 02:39:26
让我确认一下我的理解是否正确:
聊天有零个或一个音频,零个或一个视频。
音频,如果存在,恰好属于1个聊天。视频,如果它存在,恰好属于1个聊天。
这是正确的吗?如果是这样,您的DBA会介意这样的模式吗?
-Chat-
ChatID
-Audio-
ChatID <-- FK, Primary Key
Recorded
-Video-
ChatID <-- FK, Primary Key
Recorded如果是这样,我认为你可以这样做:
public class Chat
{
public int ChatID { get; set; }
public virtual Audio ChatAudio { get; set; }
public virtual Video ChatVideo { get; set; }
}
public class Audio
{
public int ChatID { get; set; }
public virtual Chat Chat { get; set; }
public DateTime Recorded { get; set; }
}
public class Video
{
public int ChatID { get; set; }
public virtual Chat Chat { get; set; }
public DateTime Recorded { get; set; }
}..。
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Audio>().HasKey(a => a.ChatID);
modelBuilder.Entity<Video>().HasKey(a => a.ChatID);
var chat = modelBuilder.Entity<Chat>();
chat
.HasOptional(c => c.ChatAudio)
.WithRequired(a => a.Chat);
chat
.HasOptional(c => c.ChatVideo)
.WithRequired(a => a.Chat);
...
}https://stackoverflow.com/questions/8481497
复制相似问题