我正在努力加快MVC,linq,razor等的速度。一些事情正在发挥作用,而其他一些事情我只是打死了那些让我感到沮丧的事情。这是我无法解决的第一个问题。在这里提出这个问题之前,我已经研究过每一条线索,这是我的第一个,所以请放轻松。我确定答案就在我的面前,但我看不到它。我可以输入14页我尝试过的东西,但是我试图保持这种简洁和重点。我已经完全破坏了我的代码,所以我从内存中提取了大部分内容,因此,它与标点符号错误无关。我道歉错误代码并不准确,因为我也从内存中提取错误代码。
我在ActionResult中有这个左连接linq查询:
public ActionResult Index()
{
var orders = from o in db.Orders
join u in db.Users on o.UserId equals u.Id into ou
where o.UserId == uId
from o in ou.DefaultIfEmpty()
select o;
Return View(orders.ToList());
}
在Index.cshtml中,我通过执行以下操作调用结果:
@foreach (var item in Model.Orders) {
@item.User.Name //(joined Users table)
@item.OrderNumber //(Orders table)
到目前为止,这么好。但是,我想在索引页面上显示的不仅仅是这个列表。所以,我可以说,我需要一个ViewModel来在同一页面上显示其他几个数据(OrdersTotal等)。但是,当我在我的模型中将我的linq查询粘贴在:
中public List<Order> GetOrders()
{
var orders = from o in db.Orders
join u in db.Users on o.UserId equals u.Id into ou
where o.UserId == uId
from o in ou.DefaultIfEmpty()
select o;
return orders.ToList();
}
它无法识别已加入的Users表,这意味着它不知道cshtml中的item.User.Name。然后我开始一个潘多拉的实验盒,我无法工作,主要是在select语句中:
select New //this complains about anonymous type
或
select New Order(o.OrderNumber,u.Id) //I can't remember the error here, but red squiggly lines
或
select New Order { OrderNumber = o.OrderNumber, UserName = u.Name} //VS complains about not referencing the Users table, it wants to put a UserName field or property stub in my model, which if I do that, then it errors in the cshtml again as I'm guessing because I don't have a UserName in my Orders table?
有几次,我得到了上面的查询,但是在尝试再次访问cshtml中的Users表时会引发异常。我的viewmodel控制器如下所示:
public ActionResult Index()
{
var ordersummary = new OrdersSummary();
var viewModel = new OrderSummary
{
Orders = ordersummary.GetOrders(),
OrdersTotal = ordersummary.GetOrdersTotal(),
};
return View(viewModel);
}
我的viewModel模型如下所示:
public class OrderSummary
{
public List<Order> Orders { get; set; }
public decimal OrdersTotal { get; set; }
public virtual User Users { get; set; }
{
我的订单模型基本上遍历数据库中的不同列,具有与上面相同的公共虚拟用户用户,这些工作正常,从ActionResult中提取列表。
public class Order
{
public int Id { get; internal set; }
public int UserId { get; set; }
public int OrderNumber { get; set; }
...
...
public virtual User Users { get; set; }
}
我不禁想到我在我的模型或控制器中做了一些根本错误的事情,而不是在linq语句的语法中。非常感谢任何帮助。
更新:我现在已经完成了一些教程,我基本上试图在这里模仿这个页面(从ViewModels开始,尽管我的OrderSummary模型来自上面的ShoppingCart GetCartItems等):
http://www.asp.net/mvc/tutorials/mvc-music-store/mvc-music-store-part-8
但是,上面的教程不需要sql join。想象一下票务系统,你有门票(订单)和技术人员(用户),你正在尝试为技术人员分配门票(每张门票一张技术,但有些门票可能没有分配给他们的技术,但也称为空)以及我是什么我试图创建的是概览部分,您可以在其中查看所有票证和分配给表格中的票据的技术,然后进一步统计数据,例如Total#of Tickets,或者最终可能是TechA拥有x#门票。所以,我需要订单数据库中的所有信息,只需要来自用户数据库的名称,然后就可以在索引页面上引入多条信息。
我注意到一些教程使用额外的表来加入ID。所以,在我的情况下,一个额外的表只有OrderId和UserId。这可能是一种更好的联接方式(因缺乏正确的术语而“加入”)?
答案 0 :(得分:0)
如果你想使用匿名类型,你可以返回IEnumerable<dynamic>
并像以前一样工作;
public IEnumerable<dynamic> GetOrders()
{
var orders = from order in db.Orders
join u in db.Users on order.UserId equals u.Id into ou
where order.UserId == uId
from user in ou.DefaultIfEmpty()
select new { order, user };
return orders.ToList();
}
var item = GetOrders().First();
item.order.Number // (Orders table)
item.user.Name // (joined Users table)
答案 1 :(得分:0)
所以,完整的答案如下:
我在评论中提到的cshtml怪异是由于:
'object' does not contain a definition for 'X'
匿名对象由编译器作为内部对象发出。剃刀 视图会自动编译成单独的程序集 ASP.NET运行时。这意味着您无法访问任何匿名用户 控制器中生成的对象。
所以,这很糟糕,它不喜欢上面的匿名查询,即使我在调试时可以看到来自两个表的信息(当我将鼠标悬停在我的cshtml中的项目上时)。无论如何,我仍然使用Joachim建议的“动态”,尽管这里有人说这可能不是最好的做事方式。但是,我不得不将我的linq查询更改为以下内容以消除匿名:
var orders = from order in db.Orders
join u in db.Users on order.UserId equals u.Id into ou
where order.UserId == uId
from user in ou.DefaultIfEmpty()
select new OrderSummary
{
OrderNumber = order.OrderNumer,
UserName = user.Name
};
这方面的诀窍是(对我来说无论如何):
那么在我的Index.cshtml中,我做的与原版类似,除了在我定义它们时调用上面的值:
@foreach (var item in Model.Orders) {
@item.UserName //(joined Users table) *This is the only line that changed.
@item.OrderNumber //(Orders table)}
我的控制器从未改变过所有这些......我认为这就是它。我希望这可以节省别人在将来尝试设置ViewModel的麻烦。活到老,学到老。我的编程术语相当薄弱,所以如果我使用了任何错误的措辞,我会道歉。祝你好运。