我正面临使用存储库模式从entiry框架执行查询的问题。
public tblUser AuthenticateUser(string userName, string password)
{
return _UnitOfWork.Repository<tblUser>().Get(x => x.UserName == userName && x.Password == password);
}
public class UnitOfWork
{
private DbEntities _context = null;
public Dictionary<Type, object> repositories = new Dictionary<Type, object>();
public UnitOfWork()
{
_context = new DbEntities();
}
public GenericRepository<T> Repository<T>() where T : class
{
if (repositories.Keys.Contains(typeof(T)) == true)
{
return repositories[typeof(T)] as GenericRepository<T>;
}
GenericRepository<T> repo = new GenericRepository<T>(_context);
repositories.Add(typeof(T), repo);
return repo;
}
}
public class GenericRepository<TEntity> where TEntity : class
{
internal DbEntities Context;
internal DbSet<TEntity> DbSet;
public GenericRepository(DbEntities context)
{
this.Context = context;
this.DbSet = context.Set<TEntity>();
}
public TEntity Get(Func<TEntity, Boolean> where)
{
IQueryable<TEntity> query = DbSet;
return query.Where(where).FirstOrDefault();
}
}
在执行查询时,在sql Server Profiler上创建的查询是
sql profiler created query (Image:1)
在sql Server Profiler上创建的查询结果从数据库中获取所有记录,之后获取 记录在c#的内存中进行过滤,但作为泛型类的get方法,查询应该在数据库服务器上执行。
但是当从实体框架直接执行查询时,
using (DbEntities context = new DbEntities())
{
return context.tblUsers.Where(x => x.UserName == userName && x.Password == password).FirstOrDefault();
}
在这种情况下,在sql Server Profiler上创建的查询是
sql profiler created query (Image:2)
我很困惑如何在存储库模式上执行查询以执行查询并过滤数据库服务器上的记录,如Image:2 请帮帮....
答案 0 :(得分:0)
您的where
参数是一个函数,它是C#代码,必须在C#中执行。它无法转换为SQL。
而是将参数类型更改为表达式:
public TEntity Get(Expression<Func<TEntity, Boolean>> where)
{
IQueryable<TEntity> query = DbSet;
return query.Where(where).FirstOrDefault();
}
Expression是一个数据结构,看起来与函数相同(从程序员的角度来看)。实体框架可以将该数据结构转换为SQL,并且可以过滤您的查询。