2013-07-12 63 views
0

我使用EF 5.0和Code First。在我的通用版本库中,我有一种逻辑方式排除记录的方法。此方法实际上执行更新,将实体字段的状态设置为false。实体框架筛选器逻辑删除记录

我想拦截我的查询,并只筛选status == true的地方。

有没有简单的方法来做到这一点?例如:

new GenericRepository<Entity>().ToList(); 
// and internally it will filter where status == true. 

回答

2

创建一个通用的方法

public IQueryable<T> All<T>(Expression<Func<T, bool>> predicate) { 

    return context.Set<T>().Where(predicate); 

} 

,如果你想要更多的东西链接到您的status财产,你必须使用反射,并通过自己构建拉姆达(因为你不能使用接口linq来实现查询)。

类似的东西(未经测试),调用通用的All方法。

public IQueryable<T>AllButDeleted<T>() { 
    var property = typeof(T).GetProperty("status"); 
    //check if T has a "status" property 
    if (property == null && || property.PropertyType != typeof(bool)) throw new ArgumentException("This entity doesn't have an status property, or it's not a boolean"); 
    //build the expression 
    //m => 
     var parameter = new ParameterExpression(typeof(T), "m"); 
    // m.status 
    Expression body = Expression.Property(parameter, property); 
    //m.status == true (which is just m.status) 
    body = Expression.IsTrue(body); 
    //m => m.status 
    var lambdaPredicate = Expression.Lambda<Func<T, bool>>(body, new[]{parameter}); 
    return All(lambdaPredicate); 
    } 
+0

谢谢!这就是我一直在寻找的。 –

2

你可以让你所有的实体实现一些IDeletable接口:

public interface IDelitable 
{ 
    bool IsDeleted { get; } 
} 

并添加约束到存储库

public class GenericRepository<T> 
    where T: class, IDelitable 

的泛型参数并添加过滤器,当你返回值:

context.Set<T>().Where(e => !e.IsDeleted) 
+0

@RaphaëlAlthaus不,它工作得很好。因为它不知道任何关于实体的接口 - 它与实现一起工作。 –

+0

@RaphaëlAlthaus我完全相信它不会,因为刚刚使用EF5验证了这个代码:) –

+1

好了,那么,我将不得不重试,thx进行测试;) –

0

您可以使用Where过滤它。

​​