1

EFを使用してデータベースの最後の10エントリを取得し、値と現在の用語が一致するかどうかを確認する必要があるメソッドがあります。これが私がこれまでに持っているものです

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() メソッドをクエリ内に移動することで、最初の試行ではすべてのレコードを取得してから上位 10 を取得していたところを明示的に上位 10 を取得しています。

テストのために、最初の where() を分割して最初にすべてのレコードを id で取得し、そのセット内で一致するパスワードを探してそのセットに対してフィルターを実行する場所も確認できます。

ご協力ありがとうございました

于 2012-05-22T16:54:15.003 に答える