2012-07-19 61 views
4

我想限制导航属性返回的模型。例如,我正在使用AuditInfo模型来记录模型的活动。一旦删除模型,将设置DeletedByDeleted属性。然而,由于没有从数据库中真正被“删除”,所以这些模型仍然会被其他模型引用的导航属性填充。导航属性的实体框架约束

AuditInfo类具有导航属性被审计

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 Comment 
{ 
    //Other attributes 

    public int AuditInfoID { get; set; } 
} 

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

+2

BlogPost.Comments如何填充?你可以通过检查BlogPost.Comments.AuditInfo.Deleted = false填充BlogPost.Comments吗? – 2012-07-19 20:28:08

+0

它使用实体框架进行填充。由于每条评论都有一个与BlogPost关联的外键,框架将自动检测一对多关系并填充导航属性。 – 2012-07-19 20:40:46

回答

5

(我假设你正在使用,因为[Key]属性的EF代码优先。)

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

  • 延迟加载:

    你的导航属性必须是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应用过滤器。急切的加载将永远加载全部评论的给定的博客文章。

  • 显式加载:

    加载父:

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

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

    当你现在加载注释可以应用过滤器可以在投影属性中应用一个过滤器:

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

不可能适用某种全局过滤策略的模型定义,以便该过滤器被应用于所有自动方法上面,没有在显式加载和显式指定它投影的例子。 (我认为你有这样一个全球模型的定义,但这是不可能的。)

0

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

+0

这应该是域模型的责任,而不是视图的。 – 2012-07-19 20:24:04

+0

@Sbossb最后一点:http://stackoverflow.com/questions/how-to-ask – podiluska 2012-07-19 20:30:29

+0

我很困惑什么点你试图做 – 2012-07-19 20:37:17

1

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

+0

我想这样做,但由于该属性是一个列表,删除的实体将被序列化为模型,然后过滤掉。我想在数据库查询期间将它们过滤掉。 – 2012-07-19 20:44:07

+0

比maby存储过程会对你有帮助吗? – steavy 2012-07-19 20:49:27