实体框架约束导航属性

Ste*_*aly 4 .net c# sql sql-server entity-framework

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

AuditInfo类

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

    //Other attributes

    public string DeletedBy { get; set; }

    public DateTime? Deleted { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

具有导航属性的类

public class BlogPost
{
    //Other attributes

    //Only return Comment where Comment.AuditInfo.Deleted is NULL
    public virtual IList<Comment> Comments { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

正在审核的类

public class Comment
{
    //Other attributes

    public int AuditInfoID { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

如何设置约束,以便只从BlogPost.Comments中删除未删除的注释(Comment.AuditInfo.Deleted为NULL)?

Sla*_*uma 5

(我假设你使用EF Code-First,因为[Key]属性.)

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

  • 延迟加载:

    您的导航属性必须virtual使延迟加载完全起作用:

    public virtual IList<Comment> Comments { get; set; }
    
    Run Code Online (Sandbox Code Playgroud)

    加载父级:

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

    您无法在此处应用过滤器.延迟加载将始终加载给定博客帖子的所有评论.

  • 渴望加载:

    var blogPost = context.BlogPosts.Include(b => b.Comments)
        .SingleOrDefault(b => b.Id == 1);
    
    Run Code Online (Sandbox Code Playgroud)

    您无法应用过滤器Include.渴望加载将始终加载给定博客帖子的所有评论.

  • 显式加载:

    加载父级:

    var blogPost = context.BlogPosts.Find(1);
    
    Run Code Online (Sandbox Code Playgroud)

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

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

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

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

无法在模型定义中应用某种全局过滤器策略,以便此过滤器自动应用于上述所有方法,而无需在显式加载和投影示例中明确指定.(我认为你有这样一个全局模型定义,但这是不可能的.)