0

目標: ウェブサイトの管理者、マネージャー、およびエージェントを一覧表示する再利用可能なドロップダウン メニューを作成すること。これらのタイプのユーザーは、.NET Simplemembership webpages_Roles および webpages_UsersInRoles テーブルによって定義されます。

これまでのところ: データベースに 25 列の UserProfile テーブルがあります。UsersContext() EF からアクセスされる、同じ名前の対応するドメイン モデルがあります。

ドロップダウン メニューには、ユーザーの FirstName、LastName、および UserId のみをリストする必要があるため、完全なドメイン モデルを操作する代わりに、次の ViewModel を作成しました。

namespace MyModels.Models.ViewModels
{
    public class AdminsAndAgentsListVM
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int UserId { get; set; }
    }
}

次に、以下を Account コントローラーに追加しました (まだ部分ビューで作業していないことに注意してください)。

public ActionResult AdminsAndAgentsList()
{
   UsersContext _db = new UsersContext(); //provides me access to UserProfiles data
   var admins = Roles.GetUsersInRole("Admin"); //gets users with this role

   var viewModel = _db.UserProfiles
       .Where(x => admins.Contains(x.UserName)); //Selects users who match UserName list
    return View(viewModel);
}

次に、リスト ビューをスキャフォールディングし、厳密に型指定された ViewModel をベースにします。

    @model IEnumerable<MyModels.Models.ViewModels.AdminsAndAgentsListVM>

@{
    ViewBag.Title = "AdminsAndAgentsList";
}

<h2>AdminsAndAgentsList</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table>
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.FirstName)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.LastName)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.UserId)
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.FirstName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.LastName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.UserId)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
            @Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
            @Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
        </td>
    </tr>
}

</table>

ビルドに成功し、Web ページを実行すると、次のエラーが表示されます。

ディクショナリに渡されたモデル アイテムのタイプは「System.Data.Entity.Infrastructure.DbQuery 1[My.Models.UserProfile]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable1[My.Models.ViewModels.AdminsAndAgentsListVM]」です。

ビューを再作成しても、UserProfile に対して強く入力すると、正常に動作します。では、代わりに ViewModel に対して強く入力できるように、これを再処理するにはどうすればよいでしょうか? 可能であれば、例を挙げてください。私は C# と MVC に不慣れで、コードを直接見ることから本当に恩恵を受けています。助けてくれてありがとう!

編集 ----------------------------- UserProfile のオブジェクトは次のとおりです。

public class UsersContext : DbContext
{
    public UsersContext()
        : base("DefaultConnection")

    {
    }

    public DbSet<UserProfile> UserProfiles { get; set; }
}

[Table("UserProfile")]
public class UserProfile
{

    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }
    public string UserName { get; set; }

    [Required]
    [ReadOnly(true)]
    [DisplayName("SubscriberID")]
    public int? SubscriberId { get; set; } //Foreign key

    [StringLength(50, ErrorMessage = "The {0} must be at least {2} characters long.")]
    [Display(Name = "First Name")]
    public string FirstName { get; set; }

    [StringLength(50, ErrorMessage = "The {0} must be at least {2} characters long.")]
    [Display(Name = "Last Name")]
    public string LastName { get; set; }

    //public DateTime DOB { get; set; }
    [DataType(DataType.Date)]
    public DateTime? DOB { get; set; } //This allows null

    public bool? Gender { get; set; }

    [Required]
    [MaxLength(250)]
    [EmailAddress]
    public string Email { get; set; }

    [MaxLength(250)]
    [EmailAddress]
    [NotEqualTo("Email", ErrorMessage = "Alt Email and Email cannot be the same.")]
    public string AltEmail { get; set; }

    [MaxLength(250)]
    [EmailAddress]
    public string FormEmail { get; set; }

    public Address Address { get; set; }

    [MaxLength(20)]
    public string Telephone { get; set; }

    [MaxLength(20)]
    public string Mobile { get; set; }

    [Required]
    [DataType(DataType.Date)]
    public DateTime DateAdded { get; set; }

    [DataType(DataType.DateTime)]
    public DateTime? LastLoginDate { get; set; }

    public bool? OffersOptIn { get; set; } //any offers we may have with us or partners

    public bool? NewsOptIn { get; set; } //newsletter

    public bool? SubscriptionOptIn { get; set; } //account, technical, renewal notices, pp invoices, pp receipts

    public bool? OrderOptIn { get; set; } //orders - workflow notices

    [DataType(DataType.DateTime)]
    public DateTime? LastUpdatedAccountDate { get; set; } //Last time user updated contact info
}
4

4 に答える 4

2

これを試して。クエリをビューモデルにキャストします。

var viewModel = _db.UserProfiles
       .Where(x => admins.Contains(x.UserName))
       .Select(x => new AdminsAndAgentsListVM { 
                        FirstName = x.FirstName,
                        LastName = x.LastName,
                        UserId = x.UserId});
于 2012-10-11T22:09:37.670 に答える
1

モデルではなく、ビューをクエリに渡します。

クエリをそのまま実行します

var query = _db.UserProfiles
           .Where(x => admins.Contains(x.UserName));

次に、ビューモデルをインスタンス化して設定します

var viewModels = new List<AdminsAndAgentsListVM>();
foreach (var item in query)
{
var viewModel = new AdminsAndAgentsListVM();
     viewodel.FirstName = item.FirstName;
     viewodel.LastName = item.LastName;
     viewodel.UserId = item.UserId;
viewModels.Add(viewModel);
}



  return View(viewModels);

もちろん、これは UserProfile と AdminsAndAgentsListVM が一致するプロパティを持っていることを前提としています。

于 2012-10-11T20:18:10.383 に答える
0

戻り行を次のように変更します。

return View(viewModel.AsEnumerable());

于 2012-10-11T20:11:13.187 に答える
0

ViewModel を選択していません。クエリで Select(x => new AdminsAndAgentsListVM を実行する必要があります。そこで ToList() も実行します。

于 2012-10-11T20:11:38.040 に答える