我想限制由导航属性返回的模型。例如,我使用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; }
}
具有导航属性的类
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)?
答案 0 :(得分: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();
无法在模型定义中应用某种全局过滤策略,以便此过滤器自动应用于所有方法,而无需在显式加载和投影中明确指定例。 (我认为你有这样一个全局模型定义,但这是不可能的。)
答案 1 :(得分:1)
maby将自定义属性添加到实体类,它将使用导航属性但过滤它并返回过滤后的数据?
答案 2 :(得分:0)
将实体映射到SQL视图,过滤掉已删除的条目。