2

私は Linq を初めて使用し、新しい MVC サイトでテストしています。私はまだ構文と機能に取り組んでいますが、解決できない問題に遭遇しました。任意の支援をいただければ幸いです。

状況:

1 - デフォルトの ASPNET メンバーシップ プロバイダーを使用するように SQL データベースをセットアップしています。標準の命名規則はそのままです (aspnet_Users、aspnet_Roles、aspnet_UsersInRole など)。

2 - 拡張ユーザー情報を提供する Users というテーブルを追加しました。FK は aspnet_User UserId (1 対 1) です。

3 - 顧客 (注文) 情報を提供する Customers というテーブルを追加しました。FK は、Users テーブルの UserId です (1 対 1)。

4 - 顧客の住所情報を提供する CustomerAddress というテーブルを追加しました。FK は Customers テーブルの CustomerId です (1 対多)。

5 - 管理者へのこの情報の表示を処理するモデルをセットアップしました

問題:

1 - このプレゼンテーション モデルに、アプリケーション内で使用可能なすべてのロールのリストと、ユーザーが現在そのロールに割り当てられているかどうかを含めたいと考えています。

2 - このプレゼンテーション モデルに、ユーザーに関連付けられたすべてのアドレスのリストを含めたい

3 - Linq クエリを使用して、この情報をプレゼンテーション モデルに戻す方法がわかりません。

これが私のプレゼンテーション モデルです (現在、ロールのプロパティを持っていますが、この情報を取得する方法を理解できていないことに注意してください。また、どのようなタイプを指定すればよいかわかりません。

namespace Lambuth.PresentationModels.ManageUsers
{
public class UserDetail
{
[Editable(false)]
[Key, ScaffoldColumn(false)]
[Display(Name="User ID")]
public Guid UserId { get; set; }

[Required]
[Editable(false)]
[StringLength(16)]
[Display(Name="User Name")]
public string UserName { get; set; }

[Editable(false)]
[ScaffoldColumn(false)]
[StringLength(16)]
[Display(Name = "Lowered User Name")]
public string LoweredUserName { get; set; }

[Required]
[Editable(false)]
[StringLength(256)]
[Display(Name = "Email")]
public string Email { get; set; }

[Editable(false)]
[ScaffoldColumn(false)]
[StringLength(256)]
[Display(Name = "Lowered Email")]
public string LoweredEmail { get; set; }

[Editable(false)]
[StringLength(16)]
[Display(Name = "Site Alias")]
public string SiteAlias { get; set; }

[Required]
[Editable(false)]
[Display(Name = "Is Approved")]
public bool IsApproved { get; set; }

[Required]
[Editable(false)]
[Display(Name = "Is Locked Out")]
public bool IsLockedOut { get; set; }

[Editable(false)]
[Display(Name = "Join Date")]
public DateTime JoinDate { get; set; }

[Editable(false)]
[Display(Name = "Full Name")]
public string FullName
{
  get
  {
    AccountInfoHelpers help = new AccountInfoHelpers();
    return help.GetFullName(this.Salutation, this.FirstName, this.LastName);
  }
  set {/*no implmentation*/}
}

[Editable(false)]
[StringLength(20)]
[Display(Name = "Salutation")]
public string Salutation { get; set; }

[Editable(false)]
[StringLength(50)]
[Display(Name = "First Name")]
public string FirstName { get; set; }

[Editable(false)]
[StringLength(50)]
[Display(Name = "Last Name")]
public string LastName { get; set; }

[Editable(false)]
[Display(Name = "Last Login Date")]
public DateTime LastLoginDate { get; set; }

[Editable(false)]
[Display(Name = "Assigned Roles")]
public virtual ICollection<UserRole> AssignedRoles { get; set; }

} }

そして、これが私が現在持っているLinqクエリです:

using (LambuthEntities context = new LambuthEntities())
  {
    var user = (from u in context.aspnet_Users
                join p in context.aspnet_Membership on u.UserId equals p.UserId
                join ux in context.Users on u.UserId equals ux.user_id
                join c in context.Customers on ux.user_id equals c.user_id
                where (ux.user_id == userId)  //userId passed in as param

                select new UserDetail
                {
                  UserId = ux.user_id,
                  UserName = u.UserName,
                  SiteAlias = ux.site_alias,
                  Email = p.Email,
                  Salutation = c.salutation,
                  FirstName = c.first_name,
                  LastName = c.last_name,
                  LastLoginDate = p.LastLoginDate,
                  IsApproved = p.IsApproved,
                  IsLockedOut = p.IsLockedOut
                }).Single();

    return user;
  }

私はここで正しい軌道に乗っていますか?アドバイスをいただければ幸いです。

ありがとうございました。

4

1 に答える 1

0

私はLinqステートメントを少し違うものにします。LinqToSql は SQL ステートメントを生成するために使用でき、SQL ステートメントのように見える機能がありますが (あなたの例でわかるように)、生成されたオブジェクトの観点からそれらを使用する傾向があります。

これが意味することは、テーブル間の結合を自分で処理する代わりに、LinqToSql ジェネレーターが既に行った作業を利用して、それらのオブジェクトを使用するということです。ビジネス オブジェクトには、関連するオブジェクトにリンクするプロパティが既にあります。

これが私があなたのlinqステートメントを行う方法です:

var user = (from u in context.aspnet_Users
            where (ux.user_id == userId)  //userId passed in as param
            select new UserDetail
            {
              UserId = u.user_id,
              UserName = u.UserName,
              SiteAlias = u.User.site_alias,
              Email = u.aspnet_Membership.Email,
              Salutation = u.User.Customer.salutation,
              FirstName = u.User.Customer.first_name,
              LastName = u.User.Customer.last_name,
              LastLoginDate = u.aspnet_Membership.LastLoginDate,
              IsApproved = u.aspnet_Membership.IsApproved,
              IsLockedOut = u.aspnet_Membership.IsLockedOut,
              AssignedRoles = u.aspnet_Roles.Select(r => r.RoleName).ToList()
            }).Single();

UserRole クラスがどのように見えるのかよくわからないので、今は文字列のコレクションしかありません。また、あなたが持っている特定のSQLスキーム(あなたが設定したプロパティ)を持っていないので、オブジェクトの関係についての説明から外れていました。

また、複数のテーブルからデータを取得する LinqToSQL ステートメントを処理する場合は、データベース呼び出しをできるだけ少なくする必要があります。そうしないと、SELECT n+1 問題が発生する可能性があります。この問題に対処する 1 つの方法は、 LinqToSqlの DataLoadOptions です。

于 2012-10-03T14:45:05.113 に答える