1

我有一种方法,我需要使用 EF 检索数据库中的最后十个条目,并检查值和当前术语之间是否匹配。这是我到目前为止所拥有的

public static int ValidatePassword(string username, string password, int securityUserId)
        {
                int validResult = 0;
                /*Need to pass to client a value based upon success or failure of validation
                 * 0 - success
                 * 1 - password has already been used in the last 10 entries
                 * 2 - password does not meet CJIS requirements
                 */
                IEnumerable<string> oldpassword = null;
                // Create a Regular Expression to determine whether or not special characters are present.
                Regex regularExpression = new Regex("[^a-z0-9]");

                //if id exists pull last ten passwords
                if (securityUserId > 0)
                {
                    long id = Convert.ToInt64(securityUserId);

                    using (var context = new SecurityEntities(string.Empty))
                    {
                        try
                        {
                            oldpassword = (from p in context.SecurityAudits
                                           where p.SecurityUserId == id &&
                                           p.OldPassword == password
                                           orderby p.ActionDate descending
                                           select p.OldPassword.Take(10).ToString()).ToList();
                        }
                        catch (Exception ex)
                        {
                            string err = string.Format("ValidateCJISPassword() was unable to return an object msg:{0}", ex.Message);
                            throw new Exception(err, ex.InnerException);
                        }
                        finally
                        {
                            context.Dispose();
                        }
                    }
                }

                else if (oldpassword == null)
                {
                    //no matching record found now check other requirements
                    if ((password.Length >= DEFAULT_CJIS_PASSWORD_MIN_LENGTH) && regularExpression.IsMatch(password) && (password != username))
                    {
                        //success
                        validResult = 0;
                    }
                    else
                    {
                        //password does not meet standard CJIS requirements
                        validResult = 2;
                    }
                }
                else
                {
                    //matching record was found
                    validResult = 1;
                }
                return validResult;
            }
}

我目前挂断的地方是查询在 ToString() 方法上引发异常

LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expression.

我仍在学习 EF 以及 linq 的工作原理,所以我不确定这里最好的方法是什么。我应该尝试将结果设置为 IEnumerable 以外的其他值,例如数组或列表,还是应该考虑另一种方法?

提前致谢,

干杯,

4

2 回答 2

1

改变这个

oldpassword = (from p in context.SecurityAudits
                   where p.SecurityUserId == id &&
                   p.OldPassword == password
                   orderby p.ActionDate descending
                   select p.OldPassword.Take(10).ToString()).ToList();

对此

oldpassword = (from p in context.SecurityAudits
               where p.SecurityUserId == id &&
               p.OldPassword == password
               orderby p.ActionDate descending
               select p.OldPassword).Take(10).ToList();

问题是您的Take(10)子句不是整个结果的一部分,而是在实际的 linq 语句中..它在它的外部占据整个结果集的前 10 个..然后你这样做ToList()会将整个事情变成一个大批

下一个问题是您刚刚创建了一个数组并将其分配给oldpassword

我在这里看不到任何对数组有任何作用的东西......

您需要执行以下操作:

  1. 声明你的字符串数组
  2. 将数组分配给 linq 查询的返回值
  3. 评估 > 0 个结果的回报
  4. 如果 > 0 则密码已在最近 10 次中使用
  5. 如果 = 0 那么新密码应该没问题,对吗?
于 2012-05-22T00:42:34.837 回答
0

现在我已经了解了我在查询中需要什么,我还可以更新 linq 语句,如下所示:

    var lastTenPassword = (from p in context.SecurityAudits.Take(10)
                                     orderby p.ActionDate descending
                                     where p.SecurityUserId == id
                                     select p.OldPassword).ToList();

   string oldpassword = lastTenPassword.Where(a => a == password).FirstOrDefault();

测试更进一步,但现在通过在查询中移动 .Take() 方法,我明确地抓取了前十名,因为我的第一次尝试将检索所有记录,然后抓取前十名。

为了进行测试,您还可以查看我在哪里打破了最初的 where() 以首先按 id 获取所有记录,然后通过在该集中查找匹配的密码对该集执行过滤器。

再次感谢您的帮助

于 2012-05-22T16:54:15.003 回答