0

ログインしているユーザーに基づいて SQL データベース (Entity Framework) でデータの行を返すロジスティクスを扱う質問があります。私は主にデスクトップ C# アプリケーションに焦点を当ててきましたが、ASP.NET MVC 4 に切り替えている間、これを理解するのに少し苦労しています (私は周りを検索しましたが、どの回答も正確に何を提供しているようには見えません)を探しています):

ASP.NET (MVC4) に組み込まれている承認を使用して、ユーザーが自分の Web サイトに関するデータ (サイト カテゴリ、URL、年齢など) をフォームに投稿できるようにし、フォームにデータを保存できるようにしたいと考えています ( Entity Framework) を、UserProfile テーブルの Id に関連付けられているデータベース (PrimaryDomainsDb と呼ばれる) に接続します。

ユーザーがボタンをクリックしてドメインのリストを表示するとき、他のユーザーの行を無視してアプリケーションにドメインのリスト (関連するデータ行) を取得させるにはどうすればよいですか?

繰り返しになりますが、私は主に、実際に大量のコードをスプーンフィードするのではなく、ロジスティクスと概念 (たとえば、外部キーを使用) と疑似コードを探しています。

誰かがベスト プラクティスのアイデアを持っている場合 (つまり、UserProfile をこの方法で PrimaryDomainDb にリンクし、EF を使用して ID に一致する行をこの方法で呼び出し、行ビューに返す)、大歓迎です。

サンプルコード:

現在、PrimaryDomain コードを最初に次のように設定しています (これには、最小/最大長などを指定するデコレータはありません)。

public class PrimaryDomain
{
    public virtual int Id { get; set; }
    public virtual string SiteName { get; set; }
    public virtual string SiteURL { get; set; }
    public virtual SitePlatforms SitePlatform { get; set; }
    public virtual decimal? SiteDA { get; set; }
    public virtual decimal? SitePA { get; set; }
    public virtual string SiteAge { get; set; }
    public virtual DateTime? LastStatusUpdate { get; set; }
    public virtual string SiteIP { get; set; }
}

そして、ASP.NET WebSecurity によって提供されるものとは異なる User クラスがあります。これは次のようになります:パスワードはおそらく完全に削除して、WebSecurity で処理する必要があると思います)。

public class User
{
    public virtual int Id { get; set; }
    public virtual string Username { get; set; }
    public virtual string Password { get; set; }
    public virtual string Email { get; set; }
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }
    public virtual string MozAccessID { get; set; }
    public virtual string MozKey { get; set; }
    public virtual decimal AccuountBalance { get; set; }

    public virtual PrivateProxy PrivateProxies { get; set; }
    public virtual PrimaryDomain PrimaryDomains { get; set; }

}

ビューのデータをプルするときは、直接注入を使用してリポジトリを介してすべてを実行します。

public interface IUserDataSource
{
    IQueryable<User> Users { get; }
    IQueryable<PrimaryDomain> PrimaryDomains { get; }

    void Save();
}

これは私の UserDb クラスで、コードが IUserDataSource を呼び出すたびに (直接インジェクションを介して) フィードされます。

public class UserDb : DbContext, IUserDataSource
{
    public UserDb()
    : base("DefaultConnection")
    {
    }

    public DbSet<User> Users { get; set; }
    public DbSet<PrimaryDomain> PrimaryDomains { get; set; }



    IQueryable<User> IUserDataSource.Users
    {
        get { return Users; }
    }

    IQueryable<PrimaryDomain> IUserDataSource.PrimaryDomains
    {
        get { return PrimaryDomains; }
    }

    void IUserDataSource.Save()
    {
        SaveChanges();
    }
}

これは、たとえば、PrimaryDomains モデルをビューに渡す方法です。

public class NetworkController : Controller
{
    //
    // GET: /Network/
    private IUserDataSource _db;

    public NetworkController(IUserDataSource db)
    {
        _db = db;
    }

    public ActionResult ListDomains()
    {
        var allDomains = _db.PrimaryDomains;
        return View(allDomains);
    }
}

しかし、PrimaryDomains リスト全体をデータ ソースから取得する代わりに、現在ログインしているユーザー ID を参照して、すべてのドメインではなく、その特定のユーザーのドメインのみをアプリケーションに表示させる方法を追加したいと考えています。ユーザー ID を参照し、それをテーブルにも追加するフォームを介してドメイン。

4

2 に答える 2

0

これはおそらくあなたが探しているものです。私があなたを正しく理解していれば、WebSecurity を使用してユーザーをログインまたは登録したいのですが、エンティティ フレームワークを使用してユーザー固有のデータを保存したいと考えています。以下のコードは、EntityFramework を使用して作成されたデータベース CodeFirst に WebSecurity テーブルを接続します。

以下のクラスを作成します(チュートリアルから)。

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public sealed class InitializeSimpleMembershipAttribute : ActionFilterAttribute
    {
        private static SimpleMembershipInitializer _initializer;
        private static object _initializerLock = new object();
        private static bool _isInitialized;

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            // Ensure ASP.NET Simple Membership is initialized only once per app start
            LazyInitializer.EnsureInitialized(ref _initializer, ref _isInitialized, ref _initializerLock);
        }

        private class SimpleMembershipInitializer
        {
            public SimpleMembershipInitializer()
            {
                try
                {
                    if(!WebSecurity.Initialized)
                        WebSecurity.InitializeDatabaseConnection("ConnectionString", "DbUsers", "UserId", "Email", autoCreateTables: true);
                }
                catch (Exception ex)
                {
                    throw new InvalidOperationException("The ASP.NET Simple Membership database could not be initialized. For more information, please see http://go.microsoft.com/fwlink/?LinkId=256588", ex);
                }
            }
        }
    }

ユーザーの登録とログ記録に必要なテーブルを作成します。魔法は 2 番目、3 番目、4 番目のパラメーターにあります。EntityFramework で作成できるのは、YOUR データベースのそれぞれテーブル、userId 列、userName 列です。WebSecurity は、そのテーブルと他の自己生成テーブルを使用して、ユーザーを管理し、登録、ログインなどを許可します。

次に、コードで最初にテーブルを作成するだけです

public class DbUser
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }
    [MaxLength(40)]
    public string Email { get; set; }
    [MinLength(3)]
    [MaxLength(30)]
    [Required]
    public string FirstName { get; set; }
    [MinLength(3)]
    [MaxLength(50)]
    [Required]
    public string LastName { get; set; }
}

次に、コントローラーからデータをクエリするだけです。以下の例では、WebSecurity メンバーシップによって保存された UserId を使用して、データベースからアカウント情報を取得します。

public ActionResult AccountInfo()
        {
            if (FormsAuthentication.CookiesSupported == true && Request.Cookies[FormsAuthentication.FormsCookieName] != null)
            {
                var userId = WebSecurity.CurrentUserId;
                var userInfo = context.Users.FirstOrDefault(x => x.UserId == userId);
                userInfo.Password = "";
                return View(userInfo);
            }
            else
            {
                ModelState.AddModelError("", "Wystąpił bląd autoryzacji, zaloguj się jeszcze raz.");
                return RedirectToAction("Login", "Account");
            }
        }

編集:

上記のようにWebSecurityをEFと統合する必要があるという事実に加えて、編集した質問について(上記のようにInitializeSimpleMmebershipAttributeクラスを作成した後、コントローラーをその属性で装飾する必要があることも忘れていました)、汎用の実装にも問題がありますリポジトリ。その行に問題がある場合:

var allDomains = _db.PrimaryDomains;

次に、汎用リポジトリの実装に関するこの記事を読むことをお勧めします。

http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net- mvc-アプリケーション

本当にシンプルにしたい場合は、インターフェースメソッドに追加するだけです

GetDomainByUserId(int userId)

そのインターフェースを次のように実装するだけです:

public class UserDb : DbContext, IUserDataSource
{
    public UserDb()
    : base("DefaultConnection")
    {
    }

    public DbSet<User> Users { get; set; }
    public DbSet<PrimaryDomain> PrimaryDomains { get; set; }



    IQueryable<User> IUserDataSource.Users
    {
        get { return Users; }
    }

    IQueryable<PrimaryDomain> IUserDataSource.PrimaryDomains
    {
        get { return PrimaryDomains; }
    }

    IQueryable<PrimaryDomain> GetDomainByUserId(int userId)
    {
        return PrimaryDomains.Where(x => x.Id == userId).ToQueryable();
    }

    void IUserDataSource.Save()
    {
        SaveChanges();
    }
}

しかし、これは非常に悪いアプローチであり、その記事を読むことを強くお勧めします.

于 2013-10-13T22:41:53.240 に答える
0

私の最初の質問は、私が達成しようとしていることに関して混乱を引き起こした可能性があります。私がやろうとしていることについて、間違ったやり方を提案したのは私のせいです。多くの調査と学習の結果、まさに私が探していたのはマルチテナント データ アーキテクチャ アプローチであることがわかりました。

于 2013-10-27T16:08:50.307 に答える