1

私はEntity Frameworkのチュートリアルに従い、ApplicationConfigモデルを作成しました(これは単純化されています)-

public class ApplicationConfig
{
    public ApplicationConfig()
    {
        this.Users = new Collection<User>();
        this.Roles = new Collection<Role>();
    }

    public string Namespace { get; set; }
    public virtual ICollection<User> Users { get; set; }
    public virtual ICollection<Role> Roles { get; set; }
}


public class User
{
    public User()
    {
        this.Roles = new Collection<Role>();
        this.ApplicationConfigs = new Collection<ApplicationConfig>();
    }

    public int UserId { get; set; }

    public string Username { get; set; }
    public string Password { get; set; }

    public virtual ICollection<Role> Roles { get; set; }
    public virtual ICollection<ApplicationConfig> ApplicationConfigs { get; set; }
}

特定のアプリケーションのユーザー名/パスワードを確認する方法があります -

public User ValidateUser(string applicationNamespace, string username, string password)
{
    var applicationConfig = GetApplicationConfig(applicationNamespace);

    User user = null;
    if (applicationConfig != null)
    {
       user = applicationConfig.Users.FirstOrDefault(u => u.Username.ToLower() == username && u.Password == password);
    }
    return user;
}

アプリケーションには数百または数千のユーザーがいる可能性がありますが、このパスワード チェックでは、一致するユーザーのみを返したいと考えています。

ICollection と上記のクエリはこの目的に適していますか?

私の主な懸念は、applicationConfig.Usersクエリを実行したいのは 1 人だけですが、何千人ものユーザーがすべて満たされることです。

または、IQueryable や IEnumerable などを使用する必要がありますか?

4

2 に答える 2

4

よく見えません。あなたの懸念は有効であり、最終的にEntity Framework (または) の a (または)IQueryable<User>に戻る を使用して、何千ものユーザーをロードした後、メモリ内ではなくデータベース内で実際にユーザーをクエリするようにする必要があります。DbSet<User>ObjectSet<User>DbContextObjectContext

これであなたのアーキテクチャをApplicationConfig正確に理解していませんが、どこかで電話する必要があります:

user = context.Users.FirstOrDefault(u =>
     u.Username.ToLower() == username && u.Password == password);

基本的に同じ LINQ ですが、の代わりにcontext(=派生したDbContext(またはObjectContext)のインスタンス) を使用しapplicationConfigます。これは、データベース内のユーザーをフィルタリングする SQL クエリに変換されます。

編集

クラスがおよびとのApplicationConfig関係を持つモデルおよびデータベース内のエンティティである場合でも、資格情報基づいて単一のデータベース クエリによってユーザーを検証できます。アプリケーションのすべてのユーザーをロードする必要はありません。たとえば、次のようになります。UserRole applicationNamespace

public User ValidateUser(string applicationNamespace,
    string username, string password)
{
    return context.ApplicationConfigs
        .Where(a => a.Namespace == applicationNamespace)
        .Select(a => a.Users
            .Where(u => u.Username.ToLower() == username &&
                u.Password == password)
            .FirstOrDefault())
        .FirstOrDefault();
}

Userまたは-エンティティにコレクションを与える場合ApplicationConfigs(以下のコメントに基づいて、1つのユーザーアカウントが多くのアプリケーションに参加できると想定しています->多対多の関係)-次のようにクエリを記述できます。

public User ValidateUser(string applicationNamespace,
    string username, string password)
{
    return context.Users
        .FirstOrDefault(u =>
            u.ApplicationConfigs.Any(a => a.Namespace == applicationNamespace) &&
            u.Username.ToLower() == username && u.Password == password);
}

Include(u => u.Roles)afterを追加することで、必要に応じてユーザーのロールを簡単に含めることができるため、後者のバージョンをお勧めしますcontext.Users

いずれにせよ、鍵となるのはcontext、1 つのステップで完全な検証を実行できるようにすることです。ApplicationConfig最初にすべてのユーザーをロードしてから、ロードされたUsersコレクションからユーザーをファイリングするなど、これを 2 つの部分に分割しないでください。

于 2013-05-23T20:15:13.100 に答える
0

いいね。リターンを簡素化できます:

public User ValidateUser(string applicationNamespace, string username, string password)
{
   var applicationConfig = GetApplicationConfig(applicationNamespace);

   if (applicationConfig != null)
   {
       return applicationConfig.Users.FirstOrDefault(u => u.Username.ToLower() == username && u.Password == password);
   }
   return null;
}
于 2013-05-23T19:54:56.890 に答える