none
[ASP.NET MVC] view要如何透過viewModel向model拿資料? RRS feed

  • 問題

  • 我的model是EF幫我寫好的

    一個table就會有一個.cs檔,像這樣:

    namespace final.Models
    {
        using System;
        using System.Collections.Generic;
        
        public partial class coupon
        {
            public coupon()
            {
                this.couponFavorite = new HashSet<couponFavorite>();
            }
        
            public int couponID { get; set; }
            public int orgID { get; set; }
            public int userID { get; set; }
            public byte[] couponImage { get; set; }
            public System.DateTime maturityDate { get; set; }
            public string couponDescribe { get; set; }
        
            public virtual User User { get; set; }
            public virtual ICollection<couponFavorite> couponFavorite { get; set; }
        }
    }

    但我的view要使用兩個以上的table,所以我就自己寫了個class把我要的model合併,變成viewModel

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    using final.Models;
    
    namespace final.Models
    {
        public class testModel
        {
            public IEnumerable<activity> activuty { get; set; }
            public IEnumerable<coupon> coupon { get; set; }
            public IEnumerable<User> user { get; set; }
        }
    }

    然後我就卡在不知道怎麼在view那邊指定我想要的model欄

    @model final.Models.testModel @foreach(var item in Model) { <div class="col-md-3"> <div class="panel panel-success"> <div class="panel-heading"> <h3 class="panel-title " style="text-align:center;color:white">

    @*這邊要拿一個叫做User的table裡的userName欄位*@ @Html.DisplayFor(modelItem => item.user) </h3> </div> <div class="panel-body"> <img src="http://pingendo.github.io/pingendo-bootstrap/assets/placeholder.png" class="img-responsive">

    @*這邊要拿一個叫做coupon的table裡的couponDescribe欄位*@

    <h4>@Html.DisplayFor(modelItem => item.coupon)</h4> <p>活動期間:104/5/8~104/5/15</p> <p>永和區民族街81巷66號1樓</p> <p> <i class="btn btn-success glyphicon glyphicon-download" title="下載優惠券"></i> <i class="btn btn-danger glyphicon glyphicon-heart" title="加入我的最愛"></i> </p> </div> </div> </div> }


    請問我要如何在view的註解處取出我想要的欄位?再按.它也不會出現欄位名稱給我選

    2015年7月22日 上午 08:16

解答

  • 我想要的結果是使用者(也就是消費者)點進優惠券頁面可以看見所有優惠券列表

    那你的應該要以 所有優惠卷(coupon)的集合 為你這張View的Model 去跑迴圈。

    這樣就可以顯示所有 業者(user)所發行的優惠卷(coupon),

    至於要顯示業者的名稱(userName) 就要用拉好的關聯去點。

    像是這樣


    2015年7月22日 下午 01:17

所有回覆

  • 你要在你註解的地方跑

    IEnumerable<User> user

    的迴圈

    ,而且你的Model根本不需要跑回圈 因為他不是list

    @model final.Models.testModel
    
    @foreach(var item in Model)


    2015年7月22日 上午 08:21
  • 我覺得你迴圈放錯地方了,放到註解的地方去試試

    @foreach(var item in Model.User)

    2015年7月22日 上午 08:23
  • 可是最外面已經包了foreach了不是嗎?

    2015年7月22日 上午 08:26
  • 可是最外面已經包了foreach了不是嗎?

    根據你testModel的設計,你應該要這樣取得資料
    @model final.Models.testModel
    
    <div class="col-md-3">
        <div class="panel panel-success">
            <div class="panel-heading">
                <h3 class="panel-title " style="text-align:center;color:white">
    
                    @*這邊要拿一個叫做User的table裡的userName欄位*@
                    <table>
                        @foreach (var item in Model.user)
                        {
                            <tr>
                                <td>@item.userName</td>
                            </tr>
                              
                        }
                    </table>
                </h3>
    
            </div>
            <div class="panel-body">
                <img src="http://pingendo.github.io/pingendo-bootstrap/assets/placeholder.png"
                        class="img-responsive">
    
                @*這邊要拿一個叫做coupon的table裡的couponDescribe欄位*@
                <h4>
                    <table>
                        @foreach (var item in Model.coupon)
                        {
                            <tr>
                                <td>@item.couponDescribe</td>
                            </tr>
                        }
                    </table>
                </h4>
                <p>活動期間:104/5/8~104/5/15</p>
                <p>永和區民族街81巷66號1樓</p>
                <p>
                    <i class="btn btn-success glyphicon glyphicon-download" title="下載優惠券"></i>
                    <i class="btn btn-danger glyphicon glyphicon-heart" title="加入我的最愛"></i>
                </p>
            </div>
        </div>
    </div>

    2015年7月22日 上午 08:38
  • loop這樣放是因為要連同div一起包進去讓他可以根據table裡有幾筆資料就跑出幾個像這樣的東西

                    <div class="col-md-3">
                        <div class="panel panel-success">
                            <div class="panel-heading">
                                <h3 class="panel-title " style="text-align:center;color:white">
                                @*從User這個tableuserName欄位*@
                                魔法義大利麵
                                </h3>
                            </div>
                            <div class="panel-body">
                                <img src="http://pingendo.github.io/pingendo-bootstrap/assets/placeholder.png"
                                     class="img-responsive">
                                <h4>
                                @*從coupon這個tablecouponDescribe欄位*@
                                凡消費滿299元 即送當日甜點一份
                                </h4>
                                <p>活動期間:104/5/8~104/5/15</p>
                                <p>永和區民族街81巷66號1樓</p>
                                <p>
                                    <i class="btn btn-success glyphicon glyphicon-download" title="下載優惠券"></i>
                                    <i class="btn btn-danger glyphicon glyphicon-heart" title="加入我的最愛"></i>
                                </p>
                            </div>
                        </div>
                    </div>

    所以我認為loop一定要放在外面

    2015年7月22日 上午 08:51
  • 也就是說你的testModel 設計有問題?!

    你為什麼要這樣設計?!?! 可以說明一下嗎?!

    namespace final.Models
    {
        public class testModel
        {
            public IEnumerable<activity> activuty { get; set; }
            public IEnumerable<coupon> coupon { get; set; }
            public IEnumerable<User> user { get; set; }
        }
    }


    2015年7月22日 上午 09:01
  • 也就是說你的testModel 設計有問題?!

    你為什麼要寫?!?! 可以說明一下嗎?!

    namespace final.Models
    {
        public class testModel
        {
            public IEnumerable<activity> activuty { get; set; }
            public IEnumerable<coupon> coupon { get; set; }
            public IEnumerable<User> user { get; set; }
        }
    }


    因為我使用的的database first的設計,EF幫我把sql server那邊建好的每個table都弄成了一個model

    可是我的view卻需要使用到2個以上的model,所以想說把它包成這樣的viewmodel讓view可以一次取用到不同的model

    2015年7月22日 上午 09:07
  • 你要在你註解的地方跑

    IEnumerable<User> user

    的迴圈

    ,而且你的Model根本不需要跑回圈 因為他不是list

    @model final.Models.testModel
    
    @foreach(var item in Model)


    意思是把

    @model final.Models.testModel

    換成

    @model IEnumerable<final.Models.testModel>

    嗎?

    這個我也試過,但還是無法

    2015年7月22日 上午 09:08
  • user 跟 coupon 的關係是一對一????

    一個使用者 對到一張優惠卷

    還是 一個使用者 對到 多張優惠卷 

    我猜關聯應該已經拉好了吧!!! 

    因為類別coupon有User的屬性

    namespace final.Models
    {
        using System;
        using System.Collections.Generic;
        
        public partial class coupon
        {
            public coupon()
            {
                this.couponFavorite = new HashSet<couponFavorite>();
            }
        
            public int couponID { get; set; }
            public int orgID { get; set; }
            public int userID { get; set; }
            public byte[] couponImage { get; set; }
            public System.DateTime maturityDate { get; set; }
            public string couponDescribe { get; set; }
        
            public virtual User User { get; set; }
            public virtual ICollection<couponFavorite> couponFavorite { get; set; }
        }
    }



    2015年7月22日 上午 09:14
  • 根據你testModel的設計,你應該要這樣取得資料

    @model final.Models.testModel
    
    <div class="col-md-3">
        <div class="panel panel-success">
            <div class="panel-heading">
                <h3 class="panel-title " style="text-align:center;color:white">
    
                    @*這邊要拿一個叫做User的table裡的userName欄位*@
                    <table>
                        @foreach (var item in Model.user)
                        {
                            <tr>
                                <td>@item.userName</td>
                            </tr>
                              
                        }
                    </table>
                </h3>
    
            </div>
            <div class="panel-body">
                <img src="http://pingendo.github.io/pingendo-bootstrap/assets/placeholder.png"
                        class="img-responsive">
    
                @*這邊要拿一個叫做coupon的table裡的couponDescribe欄位*@
                <h4>
                    <table>
                        @foreach (var item in Model.coupon)
                        {
                            <tr>
                                <td>@item.couponDescribe</td>
                            </tr>
                        }
                    </table>
                </h4>
                <p>活動期間:104/5/8~104/5/15</p>
                <p>永和區民族街81巷66號1樓</p>
                <p>
                    <i class="btn btn-success glyphicon glyphicon-download" title="下載優惠券"></i>
                    <i class="btn btn-danger glyphicon glyphicon-heart" title="加入我的最愛"></i>
                </p>
            </div>
        </div>
    </div>

    這樣子沒有把div包進去,就只能有多筆資料寫多次div了耶?

    而且@item.後面沒有userName給我選,他只有testModel裡的activuty,coupon和user給我選而已

    而不能讓我突破testmodel去拿基本的model裡的欄位來用

    2015年7月22日 上午 09:14
  • user 跟 coupon 的關係是一對一????

    一個使用者 對到一張優惠卷

    還是 一個使用者 對到 多張優惠卷 

    我猜關聯應該已經拉好了吧!!! 

    因為類別coupon有User的屬性

    namespace final.Models
    {
        using System;
        using System.Collections.Generic;
        
        public partial class coupon
        {
            public coupon()
            {
                this.couponFavorite = new HashSet<couponFavorite>();
            }
        
            public int couponID { get; set; }
            public int orgID { get; set; }
            public int userID { get; set; }
            public byte[] couponImage { get; set; }
            public System.DateTime maturityDate { get; set; }
            public string couponDescribe { get; set; }
        
            public virtual User User { get; set; }
            public virtual ICollection<couponFavorite> couponFavorite { get; set; }
        }
    }



    是一對多,一個使用者可以發行多張優惠券

    關連也確實都在建表時都拉好了

    2015年7月22日 上午 09:21
  • 這樣子沒有把div包進去,就只能有多筆資料寫多次div了耶?

    而且@item.後面沒有userName給我選,他只有testModel裡的activuty,coupon和user給我選而已

    而不能讓我突破testmodel去拿基本的model裡的欄位來用

    我會給這樣的答案是告訴你 

    你的testModel user是IEnumerable型別 他是個列表 ,要跑迴圈才能取得裡面的User

    2015年7月22日 上午 09:21
  • 這樣子沒有把div包進去,就只能有多筆資料寫多次div了耶?

    而且@item.後面沒有userName給我選,他只有testModel裡的activuty,coupon和user給我選而已

    而不能讓我突破testmodel去拿基本的model裡的欄位來用

    我會給這樣的答案是告訴你 

    你的User是IEnumerable型別 他是個列表 ,要跑迴圈才能取得裡面的User


    喔喔,這樣子我懂你的迴圈的意思了

    可是我想打

                        @foreach (var item in Model.user)
                        {
                            <tr>
                                <td>@item.userName</td>
                            </tr>
                              
                        }

    時,foreach那邊要打的"var item in Model.user"後面並不會出現user讓我選

    2015年7月22日 上午 09:27
  • 你可以把 User class 貼上來嗎?!?!

    話說你要的結果是甚麼?!?!

    多個使用者 的多個優惠娟列表!?!?

    你可以示意一下你的資料 跟 你的結果 嗎??

    我下面的結果是 "僅列出使用者A 發行的所有優惠卷"



    2015年7月22日 上午 09:44
  • 你可以把 User class 貼上來嗎?!?!

    話說你要的結果是甚麼?!?!

    多個使用者 的多個優惠娟列表!?!?

    你可以示意一下你的資料 跟 你的結果 嗎??

    我下面的結果是 "僅列出使用者A 發行的所有優惠卷"

    好的,這邊是User.cs

    namespace final.Models
    {
        using System;
        using System.Collections.Generic;
        
        public partial class User
        {
            public User()
            {
                this.activity = new HashSet<activity>();
                this.activity1 = new HashSet<activity>();
                this.coupon = new HashSet<coupon>();
                this.Seat = new HashSet<Seat>();
                this.userProduct = new HashSet<userProduct>();
                this.customer = new HashSet<customer>();
            }
        
            public int orgID { get; set; }
            public int userID { get; set; }
            public string enterpriseName { get; set; }
            public string userName { get; set; }
            public string userPassword { get; set; }
            public string category { get; set; }
            public string priceInterval { get; set; }
            public string userAddress { get; set; }
            public string userPhone { get; set; }
            public string openDay { get; set; }
            public System.TimeSpan openTime { get; set; }
            public System.TimeSpan endTime { get; set; }
            public string introduction { get; set; }
            public double mealTime { get; set; }
            public byte[] userImage { get; set; }
            public string URL { get; set; }
        
            public virtual ICollection<activity> activity { get; set; }
            public virtual ICollection<activity> activity1 { get; set; }
            public virtual ICollection<coupon> coupon { get; set; }
            public virtual ICollection<Seat> Seat { get; set; }
            public virtual ICollection<userProduct> userProduct { get; set; }
            public virtual ICollection<customer> customer { get; set; }
        }
    }
    

    (這邊先說明一下,我的User指的其實是業者,瀏覽頁面的使用者身分是消費者)

    我想要的結果是使用者(也就是消費者)點進優惠券頁面可以看見所有優惠券列表

    至於示意圖,不知道為什麼這裏老是說我帳戶沒有驗證不給發圖

    不過圖長得跟你貼出來的結果差不多,只是優惠券的使用者(業者)可能是不一樣的人

    這是適意的view code

    <div class="col-md-3">
                        <div class="panel panel-success">
                            <div class="panel-heading">
                                <h3 class="panel-title " style="text-align:center;color:white">魔法義大利麵</h3>
                            </div>
                            <div class="panel-body">
                                <img src="http://pingendo.github.io/pingendo-bootstrap/assets/placeholder.png"
                                     class="img-responsive">
                                <h4>凡消費滿299元 即送當日甜點一份</h4>
                                <p>活動期間:104/5/8~104/5/15</p>
                                <p>永和區民族街81巷66號1樓</p>
                                <p>
                                    <i class="btn btn-success glyphicon glyphicon-download" title="下載優惠券"></i>
                                    <i class="btn btn-danger glyphicon glyphicon-heart" title="加入我的最愛"></i>
                                </p>
                            </div>
                        </div>
                    </div>
    
                    <div class="col-md-3">
                        <div class="panel panel-success">
                            <div class="panel-heading">
                                <h3 class="panel-title" style="text-align:center;color:white">滿燒肉食堂</h3>
                            </div>
                            <div class="panel-body">
                                <img src="http://pingendo.github.io/pingendo-bootstrap/assets/placeholder.png"
                                     class="img-responsive">
                                <h4>
                                    嫩煎牛排丼
                                    <strike>230元</strike>200元
                                </h4>
                                <p>活動期間:104/5/8~104/5/15</p>
                                <p>永和區中正路171號1樓</p>
                                <p>
                                    <i class="btn btn-success glyphicon glyphicon-download" title="下載優惠券"></i>
                                    <i class="btn btn-danger glyphicon glyphicon-heart" title="加入我的最愛"></i>
                                </p>
                            </div>
                        </div>
                    </div>
                    <div class="col-md-3">
                        <div class="panel panel-success">
                            <div class="panel-heading">
                                <h3 class="panel-title" style="text-align:center;color:white">ken桑日式食堂</h3>
                            </div>
                            <div class="panel-body">
                                <img src="http://pingendo.github.io/pingendo-bootstrap/assets/placeholder.png"
                                     class="img-responsive">
                                <h4>可享任何主餐 9折優惠</h4>
                                <p>活動期間:104/5/8~104/5/15</p>
                                <p>永和區竹林路119巷4弄1號1樓</p>
                                <p>
                                    <i class="btn btn-success glyphicon glyphicon-download" title="下載優惠券"></i>
                                    <i class="btn btn-danger glyphicon glyphicon-heart" title="加入我的最愛"></i>
                                </p>
                            </div>
                        </div>
                    </div>
                    <div class="col-md-3">
                        <div class="panel panel-success">
                            <div class="panel-heading ">
                                <h3 class="panel-title" style="text-align:center;color:white">魔法義大利麵</h3>
                            </div>
                            <div class="panel-body">
                                <img src="http://pingendo.github.io/pingendo-bootstrap/assets/placeholder.png"
                                     class="img-responsive">
                                <h4>凡消費滿299元 即送當日甜點一份</h4>
                                <p>活動期間:104/5/8~104/5/15</p>
                                <p>永和區民族街81巷66號1樓</p>
                                <p>
                                    <i class="btn btn-success glyphicon glyphicon-download" title="下載優惠券"></i>
                                    <i class="btn btn-danger glyphicon glyphicon-heart" title="加入我的最愛"></i>
                                </p>
                            </div>
                        </div>
                    </div>
                    <div class="col-md-3">
                        <div class="panel panel-success">
                            <div class="panel-heading">
                                <h3 class="panel-title" style="text-align:center;color:white">滿燒肉食堂</h3>
                            </div>
                            <div class="panel-body">
                                <img src="http://pingendo.github.io/pingendo-bootstrap/assets/placeholder.png"
                                     class="img-responsive">
                                <h4>
                                    嫩煎牛排丼
                                    <strike>230元</strike>200元
                                </h4>
                                <p>活動期間:104/5/8~104/5/15</p>
                                <p>永和區中正路171號1樓</p>
                                <p>
                                    <i class="btn btn-success glyphicon glyphicon-download" title="下載優惠券"></i>
                                    <i class="btn btn-danger glyphicon glyphicon-heart" title="加入我的最愛"></i>
                                </p>
                            </div>
                        </div>
                    </div>

    2015年7月22日 上午 11:24
  • 我想要的結果是使用者(也就是消費者)點進優惠券頁面可以看見所有優惠券列表

    那你的應該要以 所有優惠卷(coupon)的集合 為你這張View的Model 去跑迴圈。

    這樣就可以顯示所有 業者(user)所發行的優惠卷(coupon),

    至於要顯示業者的名稱(userName) 就要用拉好的關聯去點。

    像是這樣


    2015年7月22日 下午 01:17
  • 我想要的結果是使用者(也就是消費者)點進優惠券頁面可以看見所有優惠券列表

    那你的應該要以 所有優惠卷(coupon)的集合 為你這張View的Model 去跑迴圈。

    這樣就可以顯示所有 業者(user)所發行的優惠卷(coupon),

    至於要顯示業者的名稱(userName) 就要用拉好的關聯去點。

    像是這樣

    抱歉這麼晚才來回,我順便實驗了一下

    最後真的叫得出來指定欄位了(感動).我明天再寫幾筆資料進DB測試看能不能照我想像的那樣拿資料

    這邊還有幾個問題想繼續麻煩你解惑(感謝這麼耐心的大大,第一次出來問問題就遇見這麼有耐心的你><

    問題一:Multiple Models in a Single View >> 使用 Viewmodel

    根據大大的說法,因為我的資料表設計是有關連的所以才可以這樣拿

    但我一開始的想法完全就奔著一個view要同時使用多張資料表就必須另外寫一個viewmodel來給他用

    想知道我的想法是不是哪裡有誤區?同時想請問大大怎麼會想到可以只在透過coupon去呼叫到user的東西

    問題二:比較view最上面@model的兩種區別

    view那邊要用到model時最上面都會寫個一行(一個view應該也只能寫@model這樣一行?)

    但我東看西找其實會有兩種寫法,不是很了解差別想在此請益

    一種是:@model IEnumerable<final.Models.coupon>

    這個就是大大和我原本採用的

    另一種是:@model final.Models.testModel

    這個我目前只歸納出兩個用法才會用到

    • 不寫foreach就可以用
    • 如果只是像在VS直接幫我們做好的各個controller順便建的Index時簡單的寫的@m => m.Number

    然後他們倆個無法共存,讓我常常要兩個換來換去的試,試完也沒有個結果很痛苦

    以上,感謝大大指導

    2015年7月22日 下午 08:09
  • 問題一:Multiple Models in a Single View >> 使用 Viewmodel 根據大大的說法,因為我的資料表設計是有關連的所以才可以這樣拿 但我一開始的想法完全就奔著一個view要同時使用多張資料表就必須另外寫一個viewmodel來給他用 想知道我的想法是不是哪裡有誤區?同時想請問大大怎麼會想到可以只在透過coupon去呼叫到user的東西

    你有多張表要在View使用,有很多種情況。

    你的情況比較偏向是,你知道表有關聯 可是你不知道怎麼使用關聯。
    即使沒有建立關聯,一般的作法會是用JOIN的方式,最後產生一個 ViewModel的集合。

    如果有建立關聯,其實你看看 class User 或是 coupon 的類別結構,就看得出來了。
    你說User跟coupon 是一對多 一個業者可以發行多張優惠卷

    class User 裡就有 public virtual ICollection<coupon> coupon { get; set; }
    class coupon 裡就有  public virtual User User { get; set; }
    這些東西都是在資料庫建立好之後 EF產生的。

    問題二:比較view最上面@model的兩種區別 view那邊要用到model時最上面都會寫個一行(一個view應該也只能寫@model這樣一行?) 但我東看西找其實會有兩種寫法,不是很了解差別想在此請益 一種是:@model IEnumerable<final.models.coupon>這個就是大大和我原本採用的 另一種是:@model final.Models.testModel 這個我目前只歸納出兩個用法才會用到 不寫foreach就可以用 如果只是像在VS直接幫我們做好的各個controller順便建的Index時簡單的寫的@m => m.Number 然後他們倆個無法共存,讓我常常要兩個換來換去的試,試完也沒有個結果很痛苦 </final.models.coupon>

    是的,一張View只有一個@model

    一張優惠卷 (一個物件)
    @model final.Models.coupon

    一堆優惠卷 (一個物件集合)
    @model IEnumerable<final.Models.coupon>

    一個自訂tesModel物件 且tesModel裡面有一堆優惠卷 一群業者
    @model final.Models.testModel

    列出集合,基本上都是要用跑迴圈 (for 、foreach)。
    至於你表示的 @m => m.Number 無法共存? 我就不太瞭解意思了。



    2015年7月23日 上午 03:29
  • 你的情況比較偏向是,你知道表有關聯 可是你不知道怎麼使用關聯。
    即使沒有建立關聯,一般的作法會是用JOIN的方式,最後產生一個 ViewModel的集合。

    那為什麼我不能用我之前寫的testModel那樣的ViewModel來拿到某張table的某欄位呢?

    然後之所以沒有使用join是因為我想說join是寫在view裡,可是view只有@一個model,應該無法拿到其他的model,所以覺得行不通

    至於你表示的 @m => m.Number 無法共存? 我就不太瞭解意思了。

    像是讓VS幫我們寫出來的Details就這樣寫

    @model practice0710.Models.user
    
    <dl class="dl-horizontal">
            <dt>
                <label>ID</label>
            </dt>
    
            <dd>
                @Html.DisplayFor(model => model.userID)
            </dd>
            <dt>
                @Html.DisplayNameFor(model => model.userName)
            </dt>
    
            <dd>
                @Html.DisplayFor(model => model.userName)
            </dd>
    
            <dt>
                @Html.DisplayNameFor(model => model.userPsw)
            </dt>
    
            <dd>
                @Html.DisplayFor(model => model.userPsw)
            </dd>
    
        </dl>
    2015年7月23日 上午 04:08
  • 那為什麼我不能用我之前寫的testModel那樣的ViewModel來拿到某張table的某欄位呢?

    因為

    namespace final.Models
    {
        public class testModel
        {
            public IEnumerable<activity> activuty { get; set; }
            public IEnumerable<coupon> coupon { get; set; }
            public IEnumerable<User> user { get; set; }
        }
    }

    @model final.Models.testModel

    Model.user <------他是集合、他是集合、他是集合,很重要所以要說三次 ..他不是物件

    UserName是定義在User的物件裡,而不是在 IEnumerable<User>裡面。

    我剛剛說了你要列出集合,基本上都是要跑迴圈。

    即使你要在testModel裡的某個table拿到某個欄位 你也要指定table的哪一筆資料,然後取得那個欄位。

    就例子來說,testModel裡一堆User裡 我要第九個User的 UserName的欄位。

    像是讓VS幫我們寫出來的Details就這樣寫

    哈 我還是不太懂 不能共存。

    那個產出來的View 改成甚麼樣子才會發生 你所謂的無法共存呢?!!?

    我猜應該是你抽換Model 導致HTMLhelper 找不到該Model的屬性造成的錯誤吧!


    2015年7月23日 上午 04:31
  • 我剛剛說了你要列出集合,基本上都是要跑迴圈。

    即使你要在testModel裡的某個table拿到某個欄位 你也要指定table的哪一筆資料,然後取得那個欄位。

    就例子來說,testModel裡一堆User裡 我要第九個User的 UserName的欄位。

    在引用的這上面那幾行我覺得我應該有懂一些了,但看了大大的舉例我忍不住又繼續鑽牛角尖了

    上上個回復中,大大說

     一張優惠卷 (一個物件)
    @model final.Models.coupon

    一堆優惠卷 (一個物件集合)
    @model IEnumerable<final.Models.coupon>

    那我寫@model IEnumerable<final.Models.testModel>也是拿到testModel這個物件集合阿

    然後寫回去拆出了包在裡面的User集合

    那為什麼不能進一步把

    public IEnumerable<User> user { get; set; }
    這個集合拆下來再繼續從IEnumerable<User>這個集合拆出裡面的User物件裡的Username?
    像是讓VS幫我們寫出來的Details就這樣寫

    哈 我還是不太懂 不能共存。

    那個產出來的View 改成甚麼樣子才會發生 你所謂的無法共存呢?!!?

    我猜應該是你抽換Model 導致HTMLhelper 找不到該Model的屬性造成的錯誤吧!

    不能共存我覺得我知道是為什麼了!!

    大大說了一張view只能有一個@model,所以他倆才不能共存?


    • 已編輯 Didia LIN 2015年7月23日 上午 06:32 寫錯字
    2015年7月23日 上午 06:32
  • 你會建 testModel 是因為你不知道關聯取得UserName

    所以你自訂了一個 testModel 把多個集合放進去。

    你之前表示為什麼不能直接從 testModel去得user的userName

    現在又 表示為什麼不能直接從 IEnumerable<testModel> 去取得user的userName。

    我.......... (暈倒

    我看起來 你似乎想要 Model.user.UserName 就取得UserName。

    我前面說了 Model.user 定義是一個user集合 表示你要跑迴圈列出所有的User 或是直接用linq查詢你要的User 接著取得 UserName。

    如果你硬是要用testModel去解決你的問題

    你要先跑一個 testModel.coupon的迴圈 把所有的優惠卷列表列出來

    接著用你每筆coupon的userID 去找你的User

    類似

    @model testModel
    
    foreach(var coupon in Model.coupon )
    {
        @{
        User user  = Model.user.FirstOrDefault(u => u.userID == coupon.userID);
           }
         業者名稱:  @user.UserName
    
         優惠卷描述: @coupon.couponDescribe  
    }

    可是我絕對不建議像你這樣用testModel去解決問題

    你都用EF了 要善用關聯 正所謂 "關聯拉的好 查詢沒煩惱"。

    你何苦要寫那麼複雜 那麼辛苦呢!! 是不

    別鑽了 回頭是岸

    2015年7月23日 上午 07:36
  • 如果你硬是要用testModel去解決你的問題

    你要先跑一個 testModel.coupon的迴圈 把所有的優惠卷列表列出來

    接著用你每筆coupon的userID 去找你的User

    類似

    @model testModel
    
    foreach(var coupon in Model.coupon )
    {
        @{
        User user  = Model.user.FirstOrDefault(u => u.userID == coupon.userID);
           }
         業者名稱:  @user.UserName
    
         優惠卷描述: @coupon.couponDescribe  
    }

    可是我絕對不建議像你這樣用testModel去解決問題

    你都用EF了 要善用關聯 正所謂 "關聯拉的好 查詢沒煩惱"。

    你何苦要寫那麼複雜 那麼辛苦呢!! 是不

    別鑽了 回頭是岸

    我也覺得我該回頭了QAQ,雖然覺得放過了不知道為什麼好像很受歡迎的viewModel有點不甘心

    (這邊看見大大的另一種為了滿足我的不死心寫的另一種寫法表示...覺得看見了神(不)奇(懂)的文字,還是先假裝看不見吧)

    關聯拉的好意思應該是資料庫設計要好好規劃?

    進一步就是說viewModel在我好好設計資料庫的情況下根本用不到?(震驚<<這貨為了viewModel已經耗了兩周,無果)

    2015年7月23日 下午 01:29
  • 你真的清楚 ViewModel 是用在哪的嗎...

    不是因為它 "很受歡迎" 才用它吧。


    強力監督SQL Injection問題!!

      • 小朱的技術隨手寫:http://www.dotblogs.com.tw/regionbbs/
      • 雲端學堂Facebook: http://www.facebook.com/studyazure

    2015年7月23日 下午 02:13
    版主
  •  我現在大概是不知道自己哪裡懂哪裡不懂

    使用"ViewModel"的原因要說因為他很歡迎才用感覺...也無法否認

    因為把問題歸類到"一個view使用多個model"這塊去做搜尋解決方法時,出現的就這是個

    加上一開始模模糊糊發問時,學長的示範好像也是長這樣(當時看完就只有記個大概怎麼寫,然後以那個寫法下去查範例

    上上個大大的回覆我也為了節省不夠的腦子直接歸納成:

    關聯在設計資料庫時拉好,EF抓進來就都各自有千絲萬縷的關係所以用了一個model總是能通往別的model,以後再也不用煩惱viewmodel了~

    不知道這樣子總結對不對?

    ___________________________

    SQL Injection好像還很高深感覺從來沒碰過~(校內專題老師才不指望我們

    但這次用VS寫asp.net mvc好像只能用lin-q這個很奧妙的語法,應、應該有比原來寫直接寫sql下去好?

    然後兩個參考連結有機會用到AZURE的話也會仔細研究的~<<逃避狀態


    2015年7月23日 下午 02:39
  • LINQ + Entity Framework 確實可以在不寫 SQL 的情況下寫出資料存取的程式,但不代表可以就此把 SQL 給拋棄,因為你總會有機會遇到環境不允許你用 ORM 的時候 (人不可能永遠都幸運)。該用 ADO.NET 時還是要用,MVC 也不是只能用 LINQ + EF,如果有任何書告訴你 MVC 只能用 LINQ + EF 寫資料存取,請把那本書丟掉,若是有人這樣跟你講,就裝做沒聽到。

    Model 的設計應該盡量單純化,或許你需要讀點 domain design 的書。


    強力監督SQL Injection問題!!

      • 小朱的技術隨手寫:http://www.dotblogs.com.tw/regionbbs/
      • 雲端學堂Facebook: http://www.facebook.com/studyazure

    2015年7月23日 下午 03:29
    版主
  • 該用 ADO.NET 時還是要用,MVC 也不是只能用 LINQ + EF,如果有任何書告訴你 MVC 只能用 LINQ + EF 寫資料存取,請把那本書丟掉,若是有人這樣跟你講,就裝做沒聽到。

    Model 的設計應該盡量單純化,或許你需要讀點 domain design 的書。

    ㄜ...EF不就是選擇ADO.NET後的產物嗎?

    然後我還沒有遇見任何一本書或者人這樣跟我說啦,只有建議我最後改用LINQ這樣

    然後書上的範例和網路上找到的示範剛好也用了LINQ,不知道該把SQL放在哪邊使用我就...咬著牙硬學著了

    關於Model設計,我還以為裡面只要寫get;set;就好原來還有其他的寫法(震驚

    domain design第一次看見這個詞,我會去查看相關介紹的.

    2015年7月23日 下午 04:56
  • 我簡略說明一下ViewModel的使用,

    通常EF產生出來的Model 有時候可能不符合 View的需求 所以就要針對這張View去刻ViewModel

    不符合的原因可能有很多

    像是 Model Attribute驗證跟View不適用、View需要額外的屬性 (Property) ...等等 (可能想到再補 = =a)。

    以你這個case 其實不需要用到ViewModel ,如果要用也可以。

    你首先在Model建一個

        public class CouponViewModel
        {
            public int Id { get; set; }
    
            public string Describe { get; set; }
    
            public string UserName { get; set; }
        }

    在Controller 去Parse你的ViewModel

            public ActionResult Test()
            {
                var coupons = MyDbContext.coupon; //取得所有coupon
    
                var viewModel = coupons.Select(c => new CouponViewModel()
                {
                    Id = c.couponID,
                    Describe = c.couponDescribe,
                    UserName = c.User.userName
                });
    
                return View(viewModel);
            }
    

    在你的View使用

    @model IEnumerable<WebApplication2.Models.CouponViewModel>
    
    @foreach (var coupon in Model)
    {
        <div class="col-md-3">
            <div class="panel panel-success">
                <div class="panel-heading">
                    <h3 class="panel-title " style="text-align:center;color:white">
                        @coupon.UserName
                    </h3>
                </div>
                <div class="panel-body">
                    <img src="http://pingendo.github.io/pingendo-bootstrap/assets/placeholder.png"
                         class="img-responsive">
                    <h4>
                        @coupon.Describe
                    </h4>
                    <p>活動期間:104/5/8~104/5/15</p>
                    <p>永和區民族街81巷66號1樓</p>
                    <p>
                        <i class="btn btn-success glyphicon glyphicon-download" title="下載優惠券"></i>
                        <i class="btn btn-danger glyphicon glyphicon-heart" title="加入我的最愛"></i>
                    </p>
                </div>
            </div>
        </div>
    }

    至於你自訂的 testModel ,其實也可以算是ViewModel 還是可以達到你的需求

    但是 我認為是一個 嚴重設計不良的 ViewModel  外加你的case根本不需要這麼麻煩使用 ViewModel。

    2015年7月23日 下午 07:16
  • 看了大大為了我的無理取鬧寫的範例覺得好感動

    對於大大寫的範例我感覺最深最大的不同就是在ViewModel那邊了

    大大的ViewModel真的是為了那張View所需要的欄位寫出來的

    在看見這個範例以前我一直以為不可以這麼任性的想要什麼欄位就這樣東抓西抓的寫出model

    我以為只能用IEnumerable<>先把我需要的table整個抓進

    然後大大在controller就先處理好了抓資料的指令(如果我沒有理解錯?

     var viewModel = coupons.Select(c => new CouponViewModel()
                {
                    Id = c.couponID,
                    Describe = c.couponDescribe,
                    UserName = c.User.userName
                });

    這邊又觸發了我的一個疑問:我能不能把抓資料的指令寫在view裡跳過controller呢?

    2015年7月24日 上午 07:08
  • 這邊又觸發了我的一個疑問:我能不能把抓資料的指令寫在view裡跳過controller呢?

    實際上,

    是可以這麼做的,在View裡 直接叫用DB的資料 這是沒有問題的。

    實務上,

    寫ASP.NET MVC,最好是做到Model、Controller、View 職責分離,

    職責分離好處就是 易於維護,

    Model定義了你的資料

    Controller負責跟Model拿資料 轉成ViewModel 然後交給View

    View就只是負責"顯示資料"


    2015年7月24日 上午 07:40
  • 好的,謝謝大大耐心指導!!
    2015年7月24日 上午 08:09