简体   繁体   English

实体框架限制导航属性

[英]Entity Framework constrains on navigation properties

I want to limit model that are returned by a navigational property. 我想限制导航属性返回的模型。 For example, I am using an AuditInfo model to log the activity of a model. 例如,我正在使用AuditInfo模型来记录模型的活动。 Once a model is deleted the DeletedBy and Deleted attributes are set. 删除模型后,将设置DeletedByDeleted属性。 However since nothing is ever really "deleted" from the database, these models will still be populated in navigational properties referenced by other models. 但是,由于从未真正从数据库中“删除”任何内容,因此这些模型仍将填充在其他模型引用的导航属性中。

AuditInfo Class AuditInfo类

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

    //Other attributes

    public string DeletedBy { get; set; }

    public DateTime? Deleted { get; set; }
}

Class that has a navigational properties 具有导航属性的类

public class BlogPost
{
    //Other attributes

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

Class that is being audited 正在审核的课程

public class Comment
{
    //Other attributes

    public int AuditInfoID { get; set; }
}

How would I set up a constrain so that only the non-deleted comments (Comment.AuditInfo.Deleted is NULL) from a BlogPost.Comments? 我将如何设置约束,以使BlogPost.Comments中仅未删除的注释(Comment.AuditInfo.Deleted为NULL)?

(I assume you are using EF Code-First, because of the [Key] attribute.) (由于[Key]属性,我假设您使用的是EF Code-First。)

There are different ways to load navigation properties and related entities and you can apply a filter for some of these ways but not for all: 加载导航属性和相关实体的方式有很多,您可以为其中某些方式(但不是全部)应用过滤器:

  • Lazy loading: 延迟加载:

    Your navigation property has to be virtual so that lazy loading works at all: 您的导航属性必须是virtual以便延迟加载完全起作用:

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

    Loading the parent: 加载父:

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

    You can't apply a filter here. 您不能在此处应用过滤器。 Lazy loading will always load all comments of the given blog post. 延迟加载将始终加载给定博客文章的所有评论。

  • Eager loading: 渴望加载:

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

    You can't apply a filter in Include . 您不能在Include应用过滤器。 Eager loading will always load all comments of the given blog post. 渴望加载将始终加载给定博客文章的所有评论。

  • Explicit loading: 显式加载:

    Loading the parent: 加载父:

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

    You can apply a filter when you load the comments now: 您现在可以在加载评论时应用过滤器:

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

    You can apply a filter in the projected properties: 您可以在投影的属性中应用过滤器:

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

It is not possible to apply some kind of global filter policy in the model definition so that this filter gets applied for all methods above automatically and without specifying it explicitly in the explicit loading and in the projection example. 无法在模型定义中应用某种全局过滤器策略,以使该过滤器自动应用于上述所有方法,而无需在显式加载和投影示例中明确指定。 (I think you have such a global model definition in mind, but that's not possible.) (我认为您会想到这样的全局模型定义,但这是不可能的。)

maby将自定义属性添加到实体类,该类将使用导航属性,但对其进行过滤并返回过滤后的数据?

将实体映射到SQL视图上,以过滤出删除的条目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM