C# 实体框架对导航属性的约束

C# 实体框架对导航属性的约束,c#,.net,sql,sql-server,entity-framework,C#,.net,Sql,Sql Server,Entity Framework,我想限制导航属性返回的模型。例如,我使用AuditInfo模型来记录模型的活动。删除模型后,将设置DeletedBy和deleted属性。但是,由于从未真正从数据库中“删除”任何内容,因此这些模型仍将填充在其他模型引用的导航属性中 试听信息类 public class AuditInfo { [Key] public int AuditInfoID { get; set; } //Other attributes public string DeletedBy

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

试听信息类

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 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; }
}

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

将实体映射到一个SQL视图,该视图将过滤掉已删除的条目。

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

(由于[Key]属性,我假设您首先使用的是EF代码。)

加载导航属性和相关实体有不同的方法,您可以对其中一些方法应用筛选器,但不能对所有方法应用筛选器:

  • 延迟加载:

    您的导航属性必须是
    虚拟的
    ,以便延迟加载可以正常工作:

    public virtual IList<Comment> Comments { get; set; }
    
    您不能在此应用筛选器。延迟加载将始终加载给定博客文章的所有评论

  • 快速加载:

    var blogPost = context.BlogPosts.Include(b => b.Comments)
        .SingleOrDefault(b => b.Id == 1);
    
    您不能在
    包含
    中应用筛选器。即时加载将始终加载给定博客文章的所有评论

  • 显式加载:

    正在加载父级:

    var blogPost = context.BlogPosts.Find(1);
    foreach (var comment in blogPost.Comments) // lazy loading triggered here
    {
    }
    
    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();
    

不可能在模型定义中应用某种类型的全局筛选策略,以便自动将此筛选应用于上述所有方法,而不必在显式加载和投影示例中显式指定它。(我认为您心里有这样一个全局模型定义,但这是不可能的。)

这应该是域模型的责任,而不是视图的责任。我指的是SQL视图,而不是MVC视图。BlogPost.Comments是如何填充的?您不能通过检查BlogPost.Comments.AuditionInfo.Deleted=false来填充BlogPost.Comments吗?它是使用实体框架填充的。因为每个注释都有一个与BlogPost关联的外键,所以框架将自动检测一对多关系并填充导航属性。我想这样做,但由于属性是一个列表,删除的实体将被序列化到模型中,然后过滤掉。我想在数据库查询期间过滤掉它们。那么存储过程能帮到你吗?