0

私は MVC/C# の初心者なので、簡単に行ってください。

顧客がゼロまたは多数のプロジェクトを持つ既存のデータベースがあります。ADODB エンティティ データ モデルと dbContext コード ジェネレーターから ASP.Net プロジェクトを作成しました。

Joe Bloggs (ID=7) という顧客がいます。フォームで Joe Bloggs の [プロジェクト] リンクをクリックして、彼のプロジェクトを表示します。彼は何も持っていません。彼のためにプロジェクトを作成したいので、プロジェクト コントローラーで Create アクションを呼び出します。

3 つの理由から、Joe Bloggs ID を Create アクションに渡す必要があります (必要でない場合もあります。必要な場合は教えてください)。

  1. これは Joe Bloggs のプロジェクトであるため、コントローラーに ID=7 を渡す必要があります。これにより、作成ビューのモデル データを生成するときに、彼のデフォルトの顧客 ID を設定できます。

  2. [作成] ビューで [キャンセル] ボタンを押したときに、Joe ブログに基づいて最初にフィルター処理されたプロジェクトのビューに戻りたい

  3. 保存を押したら、Joe Bloggs に基づいて、最初にフィルター処理されたプロジェクトのビューに戻りたいと思います。

とにかく、Joe Bloggs のプロジェクトが 1 つ以上ある場合は、以下のモンスターを使用して、ビュー内のモデル データから彼の ID にアクセスできます

<input type="button" title = "New Project" value="New Project" onclick="location.href='@Url.Action("Create", new { id = Model.First().Customer_ID })'" />

問題は次のとおりです。彼がプロジェクトを持っていない場合、Model.First() は何も返さないため、「親」の Customer_ID レコードを見つけることができません。

dbContext を使用してモデル クラスを生成しました (これはデータ ファーストの開発です)。上記のケースを可能にするために、これらのクラスを拡張するか、新しいクラスを作成できることがわかりました。

私の現在の回避策は、ViewBag を使用してビューアーからさまざまな ID と文字列を渡すことです > ホットポテトのようなコントローラーですが、これは 3 つの深さ (顧客 > プロジェクト > タスク) を取得し、タスクに顧客名を表示したい場合を意味します。 2回通過しました。臭い。

Project Index ビューのドロップダウンにCustomer が含まれていることに気付きました。そのための私のコードは次のとおりです。

@Html.DropDownList("Customer_ID", null, "Select a Customer to Filter", new { @onchange = "this.form.submit();" })

私はそこからハックできるかもしれませんが、実際には、このドロップダウンから2つまたは3つの深さで遠く離れている可能性のあるクラスから上に移動できるようにしたいと考えています

これは、dbContext から生成された Customer および CustomerProject クラスの要約です。

public partial class Customer
{
    public Customer()
    {
        this.Tasks = new HashSet<Task>();
        this.CustomerProjects = new HashSet<CustomerProject>();
    }

    public int Customer_ID { get; set; }
    public string Customer_Name { get; set; }

    public virtual ICollection<CustomerProject> CustomerProjects { get; set; }
}

public partial class CustomerProject
{
    public CustomerProject()
    {
        this.Tasks = new HashSet<Task>();
        this.CustomerProjectTasks = new HashSet<CustomerProjectTask>();
    }

    public int CustomerProject_ID { get; set; }
    public int Customer_ID { get; set; }
    public string Project_Name { get; set; }

    public virtual ICollection<Task> Tasks { get; set; }
    public virtual Customer Customer { get; set; }
    public virtual ICollection<CustomerProjectTask> CustomerProjectTasks { get; set; }
}

明らかな解決策があると確信していますが、私の強みはデータベースと VB6 であり、C# ではありません。

Mystere Man の提案で、ViewModel クラスを作成しましたが、少し問題があります。

これが私のモデルクラスファイルの内容です(私が理解しているように、これは既存のプロジェクトエンティティの単なるラッパーです):

namespace zzz.Models
{
    using System;
    using System.Collections.Generic;

    public class ProjectsViewModel
    {
        public int Customer_ID { get; set; }
        public ICollection<CustomerProject> CustomerProjects;
    }
}

コントローラーの Index アクションの内容は次のとおりです (既存の Project コレクションを新しい ViewModel クラスに追加したところです)。

    public ViewResult Index(int pCustomer_ID = 0, string pProjectName_Filter = "")
    {

        // Set up drop down
        ViewBag.Customer_ID = new SelectList(db.Customers.OrderBy(x => x.Customer_Name), "Customer_ID", "Customer_Name");
        //ViewBag.Selected_Customer_ID = Customer_ID;

        // If no parameters entered, show nothing
        // Otherwise optionally filter each parameter
        var projects = from p in db.CustomerProjects
            orderby p.Active, p.Project_Order
            where
            (p.Project_Name.Contains(pProjectName_Filter) || pProjectName_Filter.Equals("")) &&
            (p.Customer_ID == pCustomer_ID || pCustomer_ID.Equals(0)) &&
            !(pCustomer_ID.Equals(0) && pProjectName_Filter.Equals(""))
            select p;


        var customerprojects = new ProjectsViewModel
        {
            Customer_ID = pCustomer_ID,
            CustomerProjects = projects.ToList()
        };


        return View(customerprojects);
    }

これは私のビューからの抜粋です (私は ViewModel クラス内の Project コレクションを反復しようとしました):

@model IEnumerable<BistechPortal.Models.ProjectsViewModel>

<table>
@foreach (var item in Model.CustomerProjects)
{
<tr>
    <td>
        @Html.DisplayFor(modelItem => item.Project_Name)
    </td>
</tr>
}
</table>

Index アクションを実行すると、foreach 行で次のようになります。

'System.Collections.Generic.IEnumerable<zzzzPortal.Models.ProjectsViewModel>' does not contain a definition for 'CustomerProjects' "

翻訳してください - ViewModel 内で「CustomerProjects」コレクションが見つからないのはなぜですか?

4

1 に答える 1

0

これが、エンティティ オブジェクトをビューに直接渡してはならない理由です。ほとんどの場合、ビューは、定義されたエンティティが提供するものよりも多くの情報 (または別の情報) を必要とします。

これがビューモデルが存在する理由です。Customer_ID とプロジェクト (および必要なその他のデータ) を含むビュー モデルを作成します。これにより、ユーザーがプロジェクトを持っていなくても、Customer_ID にアクセスできます。

public class ProjectsViewModel {
     public int Customer_ID {get;set;}
     public List<CustomerProject> CustomerProjects;
}

次に、この新しいオブジェクトをビューに渡します。

(OPによって追加されました:)

このオブジェクトをビューに渡すには、CustomerProjects タイプのデータを受け入れなくなったこと、および「列挙可能な」データを取得できなくなったことをビューに伝える必要があります (これを理解するのに 3 時間かかりました)。

だからあなたの見解の変化で

@model IEnumerable<Portal.Models.CustomerProjects>

@model Portal.Models.ProjectsViewModel

また、ビューで Model.CustomerProject を反復処理する必要があるため、変更します

@foreach (var item in Model)

@foreach (var item in Model.CustomerProjects)
于 2012-09-30T18:55:55.057 に答える