如何在EF中正确实现继承,并考虑到性能

时间:2013-12-07 17:15:35

标签: c# entity-framework asp.net-mvc-4 ef-code-first

我的应用有PostsFlags。这两个都有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类需要同时考虑父FlagPost。将ParentPostIdParentFlagId添加到同一个类似乎是一种处理它的脏方法,尤其是考虑到关系映射。所以我分开了回应:

高级消息:

// 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。

如果有人有任何建议,我会保留这些建议,或者这可以让其他人免受我今天遇到的痛苦。

0 个答案:

没有答案