簡體   English   中英

了解LINQ查詢和ViewModel

[英]Understanding LINQ Queries and ViewModels

我有三個簡單的表-用戶組,人員和稱呼。 全部都有ID,Name / Desc和Active列。 還為用戶組分配了一個可選的員工ID,為員工分配了一個非可選的稱呼ID。 我想查詢這些表返回所有活躍用戶組的完整列表,與他們相關的工作人員(的話), 及其相關的敬意。

一個有效的SQL查詢如下:

        SELECT grp.ID, grp.Desc, grp.Active, sub.Name, sub.Desc
        FROM Tbl_UserGroup AS grp
        LEFT JOIN (
            SELECT st.ID, st.Name, sal.Desc
            FROM PrmTbl_Staff AS st
            LEFT JOIN PrmTbl_Salutation AS sal ON st.SalutationID = sal.ID
            WHERE 1
        ) AS sub ON grp.StaffID = sub.ID
        WHERE grp.Active = TRUE
        ORDER BY grp.ID DESC 

我有一個ViewModel如下:

public class StaffUserGroup
{
    public int GroupID { get; set; }
    public string GroupDesc { get; set; }
    public bool GroupActive { get; set; }

    public int? StaffID { get; set; }
    public string StaffName { get; set; }

    public string SalutationName { get; set; }

    public List<PrmTbl_Staff> StaffsList { get; set; }

}

並嘗試執行LINQ查詢:

IEnumerable<Tbl_UserGroup> grpsQuery;

grpsQuery = from grp in db.Tbl_UserGroups
            join sub in(
                from st in db.PrmTbl_Staffs
                join sal in db.PrmTbl_Salutations on st.SalutationID equals sal.ID
                select new { StID = st.ID, st.Name, Salt = sal.Desc }
            ) on grp.StaffID equals sub.StID
            where grp.Active = true
            orderby grp.ID descending
            select new { grp.ID, grp.Desc, grp.Active, sub.Name, sub.Salt, sub.StID };

這是在我的控制器中加載的:

        var viewModel = grpsQuery.Select(group =>
            new StaffUserGroup
            {
                GroupID = group.GroupID,
                GroupDesc = group.GroupDesc,
                GroupActive = group.GroupActive,

                StaffID = group.StaffID,
                StaffName = group.StaffName,

                SalutationName = group.SalutationName,

                StaffsList = rtrnStaff
            }
        );

請注意,intellisense在子查詢和主查詢之間標記了名稱相同的列,因此我引入了一些別名。 我還希望將所有可用人員的下拉列表傳遞給視圖,因此將其傳遞到視圖模型中。

我在LINQ語句中的select調用時遇到錯誤: Cannot implicitly convert type 'System.Linq.IQueryable<AnonymousType#4>' to '<...StaffUserGroup> An explicit conversion exists. Are you missing a cast? Cannot implicitly convert type 'System.Linq.IQueryable<AnonymousType#4>' to '<...StaffUserGroup> An explicit conversion exists. Are you missing a cast?

我不知道

  • 當我可以直接向控制器查詢所需數據時為什么需要ViewModel
  • 然后,ViewModel類實際上從查詢中檢索到的數據做了什么-是否對它進行過濾? 從中構造一個對象? 從我在PHP和MySQL的背景來看,有什么比較?
  • 如何查詢表中的特定列。 我使用select new {} ,因為我假設這是等效的?
  • 為什么上面的LINQ語句不起作用。

如果需要,我可以發布模型,視圖或控制器。 任何幫助和建議,我們將不勝感激!

問題1

當我可以直接向控制器查詢所需數據時為什么需要ViewModel

ViewModel是您編寫的POCO ,它精確定義了視圖正確顯示自身所需的內容。

例如,假設您有一個歡迎用戶的頁面(視圖)。

歡迎, 鮑勃 您最后一次訪問是2013-10-11

ViewModel是一個簡單的類,用於精確定義視圖所需的內容。

  1. 用戶名
  2. 用戶的最后訪問

因此:

public class UserDetailsViewModel
{
    public string FirstName { get; set; }
    public DateTime LastVisit { get; set; }
}

通常,由控制器負責創建ViewModel,確保已填充,將其提供給視圖並最終返回視圖。 控制器沒有做其他事情。 它的責任是有限的,並且動作中的代碼應該很小。

您這樣做的原因是因為它是一種好習慣 但這還不夠好,讓我解釋一下。

可以簡單地運行查詢,返回某個域對象(例如,用戶列表)的IEnumerable並將其提供給視圖。 這是在許多MVC演示中完成的。 問題是它非常有限/有限制性。 如果您想稍后更改視圖顯示,會發生什么? 如果域模型稍有變化,會發生什么? 當事物井井有條且關注點分離時,管理和更改事物變得更加容易。

問題2

然后,ViewModel類實際上對從查詢中檢索到的數據做了什么-是否對它進行過濾? 從中構造一個對象? 從我在PHP和MySQL的背景來看,有什么比較?

ViewModel是某些架構模式(例如MVCMVVM )固有的(或至少通用的)概念。 ViewModel並沒有真正“做”任何事情。 它沒有任何邏輯。 它沒有方法。 它僅包含屬性(和屬性)列表,這些列表定義使用此ViewModel的視圖將需要什么。

沒有完全等效的PHP,因為ViewModel並非特定於.NET。 這只是與MVC,MVVM等相關的概念。 等效的PHP將是PHP MVC ViewModel。 請記住,ASP.NET MVC只是MVC模式的實現。 PHP具有自己的MVC實現。

問題3

如何查詢表中的特定列。 我使用select new {},因為我假設這是等效的?

這取決於您的操作方式。 EntityFramework是一個對象關系映射器,通常在ASP.NET MVC應用程序中使用。 這樣,您就不會直接查詢基礎存儲或列。 相反,EF會將表和列映射到.NET對象,然后您對它們進行操作。

我建議您嘗試處理對象,而不是隨便創建匿名類型並嘗試獲取特定列。 請記住, LINQ不是SQL 該方法不應該是“查詢此表,在此子句中獲取這些列”,而應該是“從這組對象中,在這里子句中獲取該對象”。

例如:

var query = from user in Users
            where user.FirstName == "Bob"
            select user;

問題4

為什么上面的LINQ語句不起作用。

如描述所述,您正在嘗試為StaffUserGroup的IEnumerable提供匿名的IEnumerable。 我相信這是因為您選擇事物以填充ViewModel的方式。 在不了解事物結構的情況下很難修復代碼。 我在這里的建議是看看其他人在MVC中如何進行LINQ / EntityFramework 在您熟悉事物的工作方式之前,只需進行一點練習即可。

看來您可能正在嘗試放入新類型的物品

select new { grp.ID, grp.Desc, grp.Active, sub.Name, sub.Salt, sub.St }

放入用於類型物品的集合中

IEnumerable<Tbl_UserGroup> grpsQuery;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM