我的应用有Posts
和Flags
。这两个都有Responses
,其中Comments
。
Post
Response
Comment
Flag
Response
Comment
我正在尝试尽可能简单而正确地在EF中对此进行建模,但我不确定我是否会继续使用继承。这就是我所拥有的:
public class Post {
[Key]
[Required]
public int PostId { get; set; }
public virtual ICollection<PostResponse> Responses { get; private set; }
}
public class Flag {
[Key]
[Required]
public int FlagId { get; set; }
public virtual ICollection<FlagResponse> Responses { get; private set; }
}
我想在这里只使用通用Response
,但我的Response类需要同时考虑父Flag
和Post
。将ParentPostId
和ParentFlagId
添加到同一个类似乎是一种处理它的脏方法,尤其是考虑到关系映射。所以我分开了回应:
高级消息:
// Comments, Posts, Responses all have these properties
public abstract class Message {
[Required]
public int PosterId { get; set; }
public virtual User Poster { get; set; }
public string RawContent { get; set; }
}
对策:
public abstract class Response : Message {
[Key]
[Required]
public int ResponseId { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
}
// will be used by Posts only
public class PostResponse : Response {
[Required]
public int ParentPostId { get; set; }
public virtual Post Post { get; set; }
}
// will be used by Flags only
public class FlagResponse : Response {
[Required]
public int ParentFlagId { get; set; }
public virtual Flag Flag { get; set; }
}
所以看,然后我必须考虑评论中的差异:
注释:
public abstract class Comment : Message {
[Key]
[Required]
public int CommentId { get; set; }
}
// will be used by PostResponses only
public class PostComment : Comment {
[Required]
public int ResponseId { get; set; }
public virtual PostResponse Response { get; set; }
}
// will be used by FlagResponses only
public class FlagComment : Comment {
[Required]
public int ResponseId { get; set; }
public virtual PostResponse Response { get; set; }
}
所以我已经加强了我的架构,现在我的FluentAPI codefirst配置会变得棘手,但我的逻辑现在可以很容易地区分类型并且数据被标准化。
感觉感觉比将所有内容整合到单个模型中要差,但我不确定这是否接近最佳实践,尤其是在性能问题上。性能是设计的最高优先级。
更新
在用Code-First尝试实现TPH继承几乎整个下午之后,我已经举起手来。看到这个问题:
EF Inheritance and Foreign Keys
所以我认为最便宜和后期性能的解决方案是为我添加可选的FK ID到Response对象 - 一个用于FlagId,另一个用于PostId。稍微加强我的验证,与规范化相反,但不要使我的模式复杂化并为TPC或TPT中的查询引入更多连接,并避免在这种情况下自带仇恨。我认为我正在做的是蛮力TPH。
如果有人有任何建议,我会保留这些建议,或者这可以让其他人免受我今天遇到的痛苦。