Eam*_*onn 1 c# sql linq visual-studio asp.net-mvc-4
我有三个简单的表 - 用户组,工作人员和称呼.所有都有ID,名称/描述和活动列.还为用户组分配了可选的员工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
Run Code Online (Sandbox Code Playgroud)
我有一个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; }
}
Run Code Online (Sandbox Code Playgroud)
并尝试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 };
Run Code Online (Sandbox Code Playgroud)
哪个加载到我的控制器中:
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
}
);
Run Code Online (Sandbox Code Playgroud)
请注意,intellisense在子查询和主查询之间标记了相同名称的列,因此我引入了一些别名.我还希望向视图传递所有可用人员的下拉列表,因此视图模型中的列表.
我在LINQ语句中的select调用上遇到错误: Cannot implicitly convert type 'System.Linq.IQueryable<AnonymousType#4>' to '<...StaffUserGroup> An explicit conversion exists. Are you missing a cast?
我不知道
select new {},因为我假设这相当于?如果需要,我可以发布模型,视图或控制器.非常感谢任何帮助和建议!
当我可以直接向Controller查询我需要的数据时,为什么需要ViewModel
ViewModel是您编写的POCO,它可以准确定义视图所需的内容,以便正确显示自身.
例如,假设您有一个欢迎用户的页面(视图).
欢迎,鲍勃.您的上次访问是2013-10-11.
ViewModel是一个简单的类,它完全定义了视图所需的内容.
因此:
public class UserDetailsViewModel
{
public string FirstName { get; set; }
public DateTime LastVisit { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
(通常)控制器负责创建ViewModel,确保它已填充,将其提供给视图并最终返回视图.控制器没有做太多其他事情; 它的职责是有限的,行动中的代码应该相当小.
你这样做的原因是因为这是一个很好的做法.但这还不够好,让我解释一下.
可以简单地运行查询,返回某个域对象的IEnumerable(例如用户列表)并将其提供给视图.这是在许多MVC演示中完成的.问题是它非常有限/限制.如果要更改以后显示的视图会发生什么?如果域模型略有变化会发生什么?当整齐有序且关注点分离时,管理和更改事物会更容易.
然后ViewModel类实际上对从查询中检索的数据做了什么 - 它是否过滤了它?从中构造一个对象?从我在PHP和MySQL的背景下,将会有什么比较?
ViewModel是某些体系结构(或至少是常见的)某些体系结构模式(如MVC和MVVM)的概念.ViewModel并没有真正"做"任何事情.它没有任何逻辑; 它没有方法.它只包含一个属性列表(和属性),用于定义使用此ViewModel的视图所需的内容.
由于ViewModel不是特定于.NET,因此没有完全相同的PHP.它只是一个与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;
Run Code Online (Sandbox Code Playgroud)
为什么上面的LINQ语句不起作用.
正如描述所说,你试图给一个IEnumerable的StaffUserGroup一个IEnumerable的匿名.我相信这是因为你选择的东西是为了填充你的ViewModel.如果不了解事物的结构,很难修复代码.我在这里的建议是看看其他人是如何在MVC中进行LINQ/EntityFramework的.它只需要一些练习,直到你对事情的运作方式感到满意.
| 归档时间: |
|
| 查看次数: |
4251 次 |
| 最近记录: |