[英]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?
我不知道
select new {}
,因為我假設這是等效的? 如果需要,我可以發布模型,視圖或控制器。 任何幫助和建議,我們將不勝感激!
當我可以直接向控制器查詢所需數據時為什么需要ViewModel
ViewModel是您編寫的POCO ,它精確定義了視圖正確顯示自身所需的內容。
例如,假設您有一個歡迎用戶的頁面(視圖)。
歡迎, 鮑勃 。 您最后一次訪問是2013-10-11 。
ViewModel是一個簡單的類,用於精確定義視圖所需的內容。
因此:
public class UserDetailsViewModel
{
public string FirstName { get; set; }
public DateTime LastVisit { get; set; }
}
通常,由控制器負責創建ViewModel,確保已填充,將其提供給視圖並最終返回視圖。 控制器沒有做其他事情。 它的責任是有限的,並且動作中的代碼應該很小。
您這樣做的原因是因為它是一種好習慣 。 但這還不夠好,讓我解釋一下。
可以簡單地運行查詢,返回某個域對象(例如,用戶列表)的IEnumerable並將其提供給視圖。 這是在許多MVC演示中完成的。 問題是它非常有限/有限制性。 如果您想稍后更改視圖顯示,會發生什么? 如果域模型稍有變化,會發生什么? 當事物井井有條且關注點分離時,管理和更改事物變得更加容易。
然后,ViewModel類實際上對從查詢中檢索到的數據做了什么-是否對它進行過濾? 從中構造一個對象? 從我在PHP和MySQL的背景來看,有什么比較?
ViewModel是某些架構模式(例如MVC和MVVM )固有的(或至少通用的)概念。 ViewModel並沒有真正“做”任何事情。 它沒有任何邏輯。 它沒有方法。 它僅包含屬性(和屬性)列表,這些列表定義使用此ViewModel的視圖將需要什么。
沒有完全等效的PHP,因為ViewModel並非特定於.NET。 這只是與MVC,MVVM等相關的概念。 等效的PHP將是PHP MVC ViewModel。 請記住,ASP.NET MVC只是MVC模式的實現。 PHP具有自己的MVC實現。
如何查詢表中的特定列。 我使用select new {},因為我假設這是等效的?
這取決於您的操作方式。 EntityFramework是一個對象關系映射器,通常在ASP.NET MVC應用程序中使用。 這樣,您就不會直接查詢基礎存儲或列。 相反,EF會將表和列映射到.NET對象,然后您對它們進行操作。
我建議您嘗試處理對象,而不是隨便創建匿名類型並嘗試獲取特定列。 請記住, LINQ不是SQL 。 該方法不應該是“查詢此表,在此子句中獲取這些列”,而應該是“從這組對象中,在這里子句中獲取該對象”。
例如:
var query = from user in Users
where user.FirstName == "Bob"
select user;
為什么上面的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.