C# 实体框架:通用存储库中的Include和Where子句

C# 实体框架:通用存储库中的Include和Where子句,c#,sql,frameworks,repository,entity,C#,Sql,Frameworks,Repository,Entity,我正在使用实体框架(对象上下文)检查通用存储库的可能性 我有一个接口 interface IRepository<T> where T : class { IList<T> GetItems(Func<T, bool> Where, params string[] Navigations); } class GenericRepository<T> : IRepository<T> whe

我正在使用实体框架(对象上下文)检查通用存储库的可能性

我有一个接口

    interface IRepository<T> where T : class
    {
       IList<T> GetItems(Func<T, bool> Where, params string[] Navigations);
    }
    class GenericRepository<T> : IRepository<T> where T : class
    {
       public IList<T> GetItems(Func<T, bool> Where, params string[] Navigations)
       {
           List<T> list;
           using(var ctx = new Context())
           {
               IQueryable<T> query = ctx.CreateObjectSet<T>();

               foreach (string nav in Navigations)
                    (query as ObjectQuery<O>).Include(nav);

               list = query.Where(Where).ToList<T>();
           }
           return list;
       } 
    }
接口i假设,其中T:class
{
IList GetItems(Func-Where,参数字符串[]导航);
}
以及实现接口的类

    interface IRepository<T> where T : class
    {
       IList<T> GetItems(Func<T, bool> Where, params string[] Navigations);
    }
    class GenericRepository<T> : IRepository<T> where T : class
    {
       public IList<T> GetItems(Func<T, bool> Where, params string[] Navigations)
       {
           List<T> list;
           using(var ctx = new Context())
           {
               IQueryable<T> query = ctx.CreateObjectSet<T>();

               foreach (string nav in Navigations)
                    (query as ObjectQuery<O>).Include(nav);

               list = query.Where(Where).ToList<T>();
           }
           return list;
       } 
    }
class GenericRepository:IRepository,其中T:class
{
公共IList GetItems(Func-Where,参数字符串[]导航)
{
名单;
使用(var ctx=new Context())
{
IQueryable query=ctx.CreateObjectSet();
foreach(导航中的字符串导航)
(作为ObjectQuery进行查询)。包括(nav);
list=query.Where(Where.ToList();
}
退货清单;
} 
}
然后我有另一个扩展GenericRepository的类。并实现另一个接口(现在不导入,因为该接口当前只是扩展了IRepository,没有添加任何功能)

class EmployeeRepository:GenericRepository,IEEmployeeRepository
{
}
当我想从存储库中获取数据时,我会执行以下操作:

    private void Test()
    {
        IEmployeeRepository rep = new EmployeeRepository();
        IList<Employee> list = rep.GetItems(
                                            e => e.Department.Name.Contains("Os")
                                            && e.Role.Type == 2,
                                            "Department", "Role"
                                           );
    }
private void Test()
{
IEEmployeeRepository rep=新员工Repository();
IList list=rep.GetItems(
e=>e.Department.Name.Contains(“Os”)
&&e.Role.Type==2,
“部门”、“角色”
);
}
这里我得到一个错误,说e.Department为空(我相信我在角色上也得到了一个)

该模型有三个实体

  • 雇员
  • 角色
第一部门..*员工 角色1..1员工

有可能像我一样在引用表上添加预测吗?(有一些变化)


谢谢

您确定所有员工都有一个部门吗?那个部门有人吗?
否则,我将添加一个检查e.Department是否为null的检查。首先,使用
表达式
而不是
Func

如果使用
Func
,将在应用谓词之前进行枚举

这也许足够了

如果不是,则添加一些空检查

IList<Employee> list = rep.GetItems(
                                     e => e.Department != null && e.Department.Name.Contains("Os")
                                     && e.Role != null && e.Role.Type == 2,
                                     "Department", "Role"
                                    );
IList list=rep.GetItems(
e=>e.Department!=null&&e.Department.Name.Contains(“操作系统”)
&&e.Role!=null&&e.Role.Type==2,
“部门”、“角色”
);
最后,我将GenericRepository的实现更改为

class GenericRepository<T> : IRepository<T> where T : class
    {
       public IList<T> GetItems(Expression<Func<T, bool>> predicate, params string[] navigationProperties)
       {
           List<T> list;
           using(var ctx = new Context())
           {
               var query = ctx.Set<T>().AsQueryable();

               foreach (string navigationProperty in navigationProperties)
                    query = query.Include(navigationProperty);//got to reaffect it.

               list = query.Where(predicate).ToList<T>();
           }
           return list;
       } 
    }
class GenericRepository:IRepository,其中T:class
{
公共IList GetItems(表达式谓词,参数字符串[]navigationProperties)
{
名单;
使用(var ctx=new Context())
{
var query=ctx.Set().AsQueryable();
foreach(navigationProperties中的字符串navigationProperty)
query=query.Include(navigationProperty);//必须重新生效。
list=query.Where(谓词).ToList();
}
退货清单;
} 
}

太棒了!谢谢表达时间从5000毫秒下降到现在的581毫秒。因为我使用where发出查询,而不是在内存中加载,然后作为IEnumerable进行过滤!那确实更好;)对于集合,我认为
CreateObjectSet
不会有太大变化。但包含的部分无论如何都应该更正。