EF是否从Db获取所有数据然后执行过滤?

时间:2014-02-19 05:12:21

标签: c# entity-framework

我先将一个Ado.net应用程序转换为EFcode。 但我觉得EF很慢。

示例

检查用户登录密码的Ado.net代码

 string strsql = "select Id from Users where UserName = '" + txtUserName.Text.trim() + "' and Password = "" + txtPassword.text.trim() + "'";
 DataTable dt=dab.Fill(strsql,CommandType.Text).Tables[0];;
 if(dt.Rows.Count > 0)
 {
    LogInID= dt.Rows[0]["Id"].ToString();
 }

EF代码

LogInID= UnitOfWork.UsersRepository.Entities.Where(x => x.UserName  ==  txtUserName.Text && x.Password   ==  txtPassword .Text ).Select(x => x.Id).FirstOrDefault();

第二个代码非常慢。在过滤之前,EF是否从Db中获取所有数据?或者还有什么不对吗?

编辑:

My GenericRepository如下所示

public class GenericRepository<TEntity> : IRepository<TEntity> where TEntity : class
{
 public DbContext _dbContext;
 DbSet<TEntity> dbSet;
 public GenericRepository(DbContext dbContext)
 {
   this._dbContext = dbContext;
   this.dbSet = _dbContext.Set<TEntity>();
 }

 public IQueryable<TEntity> Entities
 {
  get { return dbSet; }
 }
}

在工作单元

private IRepository<Users> _UsersRepository;
public IRepository<Users> UsersRepository
{
   get
   {
       if (this._UsersRepository == null)
        {
           this._UsersRepository = new CouponRepository<Users>(_dbContext);
         }
         return _UsersRepository;
     }
}

2 个答案:

答案 0 :(得分:4)

不,实体框架不会加载所有行,除非你告诉它,或者你将DbSet转换为IEnumerable,你的代码可能就是这样。

我会看UnitOfWork.UsersRepository.Entities,看看它在做什么。因为此代码不适用于Entity Framework:

.Where(x => x.UserName == txtUserName.Text.trim() 
         && x.Password == txtPassword.Text.trim())

两个修剪函数(首先,函数应该是Trim())应该生成一个实体框架错误,上面写着

  

“LINQ to Entities无法识别方法'System.String Trim()'方法,并且此方法无法转换为商店表达式”。

如果不是,则建议您的数据集在处理之前转换为IEnumerable,这意味着它将返回所有行。

作为旁注,这里展示了许多严重的安全漏洞。您的ado代码具有sql注入漏洞,可能导致您的系统被恶意软件所拥有,并且您显然是以明文形式存储密码,因为您正在进行直接比较..这意味着在您的数据库受到攻击后,攻击者现在拥有用户名和他们可以使用明文密码攻击其他网站上的用户,希望他们在其他地方使用相同的用户名和密码。

答案 1 :(得分:2)

不,EF没有。实体框架在获取数据时,动态构造将在返回数据之前在数据库服务器上执行的SQL查询。这意味着过滤将由数据库服务器应用,而不是由EF。

我建议您确保延迟加载已关闭,因为已知延迟加载会引入性能问题。