4

我想限制导航属性返回的模型。例如,我正在使用AuditInfo模型来记录模型的活动。删除模型后,将设置DeletedByDeleted属性。但是,由于没有真正从数据库中“删除”任何内容,因此这些模型仍将填充到其他模型引用的导航属性中。

审计信息类

public class AuditInfo
{
    [Key]
    public int AuditInfoID { get; set; }

    //Other attributes

    public string DeletedBy { get; set; }

    public DateTime? Deleted { get; set; }
}

具有导航属性的类

public class BlogPost
{
    //Other attributes

    //Only return Comment where Comment.AuditInfo.Deleted is NULL
    public virtual IList<Comment> Comments { get; set; }
}

正在审核的班级

public class Comment
{
    //Other attributes

    public int AuditInfoID { get; set; }
}

我将如何设置约束,以便只有来自 BlogPost.Comments 的未删除评论(Comment.AuditInfo.Deleted 为 NULL)?

4

3 回答 3

5

(我假设您使用的是 EF Code-First,因为该[Key]属性。)

加载导航属性和相关实体的方法有多种,您可以为其中一些方式应用过滤器,但不是全部:

  • 延迟加载:

    您的导航属性必须virtual使延迟加载完全有效:

    public virtual IList<Comment> Comments { get; set; }
    

    加载父级:

    var blogPost = context.BlogPosts.Find(1);
    foreach (var comment in blogPost.Comments) // lazy loading triggered here
    {
    }
    

    您不能在此处应用过滤器。延迟加载将始终加载给定博客文章的所有评论。

  • 急切加载:

    var blogPost = context.BlogPosts.Include(b => b.Comments)
        .SingleOrDefault(b => b.Id == 1);
    

    您不能在 中应用过滤器Include。急切加载将始终加载给定博客文章的所有评论。

  • 显式加载:

    加载父级:

    var blogPost = context.BlogPosts.Find(1);
    

    您现在可以在加载评论时应用过滤器:

    context.Entry(blogPost).Collection(b => b.Comments).Query()
        .Where(c => !c.AuditInfo.Deleted.HasValue)
        .Load();
    
  • 投影:

    您可以在投影属性中应用过滤器:

    var blogPost = context.BlogPosts
        .Where(b => b.Id == 1)
        .Select(b => new
        {
            BlogPost = b,
            Comments = b.Comments.Where(c => !c.AuditInfo.Deleted.HasValue)
        })
        .SingleOrDefault();
    

不可能在模型定义中应用某种全局过滤策略,以便自动将这个过滤器应用于上述所有方法,并且无需在显式加载和投影示例中明确指定它。(我认为您已经想到了这样一个全局模型定义,但这是不可能的。)

于 2012-07-19T21:13:38.403 回答
1

可以向实体类添加一个自定义属性,它将使用导航属性但对其进行过滤并返回过滤后的数据?

于 2012-07-19T20:37:54.100 回答
0

将实体映射到筛选出已删除条目的 SQL 视图。

于 2012-07-19T20:22:48.517 回答