这个我的代码和这个Action中的每一行都会做一些事情并从数据库中检索一些记录,让我举一个关于这个Action的例子,这个Action会显示Ordre和那个ordre下的产品,这意味着Ordre(1212) )可能有1个产品或多个产品,但我的代码只显示了该记录的一个记录而不是全部,所以我的问题是如何将此操作的返回记录列入列表?!或者我应该做别的事情!谁能指引我朝正确的方向发展? THX
控制器中的代码:
public ActionResult OrdreOpenDetails(string id)
{
DataContext data_2 = new DataContext();
Ordre_Open_Details_VM oodvm = new Ordre_Open_Details_VM();
oodvm.SalesLine = data_2.Sales_Line.FirstOrDefault(n => n.Document_No_ == id);
oodvm.SalesHeader = data_2.Sales_Header.FirstOrDefault(m => m.No_ == oodvm.SalesLine.Document_No_);
oodvm.SalesPersonPurchasers = data_2.Salesperson_Purchasers.FirstOrDefault(h=>h.Code == oodvm.SalesHeader.Salesperson_Code);
oodvm.SalesCommentLine = data_2.Sales_Comment_Line.FirstOrDefault(z => z.No_ == oodvm.SalesLine.Document_No_);
oodvm.PurchaseLine = data_2.Purchase_Line.FirstOrDefault(t=>t.Document_No_ == oodvm.SalesLine.Købsordrenr_);
return View(oodvm);
}
我的ViewModel类:
public class Ordre_Open_Details_VM
{
public Sales_Header SalesHeader { get; set; }
public Sales_Line SalesLine { get; set; }
public Purchase_Line PurchaseLine { get; set; }
public Salesperson_Purchasers SalesPersonPurchasers { get; set; }
public Sales_Comment_Line SalesCommentLine { get; set; }
}
观点中的守则:
@model DBhandling.Ordre_Open_Details_VM
<h2>OrdreOpenDetails</h2>
<div class="content">
<div class="container-fluid">
<div class="row">
<div class="col-lg-4 col-md-5">
<div class="card">
<div class="card-header" data-background-color="purple">
<h4 class="title">Detaljer</h4>
@*<p class="category">Detaljer <span>»</span> Order nr <span>»</span> @Model.SalesInvoiceHeader.Order_No_</p>*@
</div>
<div class="card-content">
<form>
<div class="row">
<div class="col-md-6">
<div class="form-group label-floating">
<label>Order nr.</label>
<input type="text" class="form-control border-input" disabled value="@Model.SalesHeader.No_">
</div>
</div>
<div class="col-md-6">
<div class="form-group label-floating">
<label>vare nummer</label>
<input type="text" class="form-control border-input" disabled value="@Model.SalesLine.No_">
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group label-floating">
<label>Forventet levering</label>
<input type="datetime" class="form-control border-input" disabled value="@Model.SalesLine.Planned_Delivery_Date">
</div>
</div>
<div class="col-md-6">
<div class="form-group label-floating">
<label>Forventet levering Direkte</label>
<input type="datetime" class="form-control border-input" disabled value="@(Model.PurchaseLine != null ? Model.PurchaseLine.Planned_Receipt_Date :(DateTime?)null )">
</div>
</div>
<div class="col-md-6">
<div class="form-group label-floating">
<label>Sales Person</label>
<input type="text" class="form-control border-input" disabled value="@Model.SalesPersonPurchasers.Name">
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="form-group label-floating">
<label>Comment</label>
<input type="text" class="form-control border-input" disabled value="@(Model.SalesCommentLine != null ? Model.SalesCommentLine.Comment : "No Comment")">
</div>
</div>
</div>
<div class="clearfix"></div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
答案 0 :(得分:0)
编辑:我看到您的LINQ条件是基于SalesLine分配中设置的ID的值? (m => m.No_ == oodvm.SalesLine.Document_No_
)这不是一个非常聪明的做法,更改此逻辑以根据数据本身中的ID选择订单,而不是基于您之前检索的内容,否则我所描述的方法将无效。我不知道你的数据是如何设置的,所以我只是要离开&#34; condition&#34;在SelectMany函数调用中。
您可以将视图模型类更改为包含每个对象的列表,而不仅仅是一个实例
public class Ordre_Open_Details_VM
{
public List<Sales_Header> SalesHeader { get; set; }
public List<Sales_Line> SalesLine { get; set; }
public List<Purchase_Line> PurchaseLine { get; set; }
public List<Salesperson_Purchasers> SalesPersonPurchasers { get; set; }
public List<Sales_Comment_Line> SalesCommentLine { get; set; }
}
然后,您可以使用SelectMany Linq方法检索满足条件的所有订单。
oodvm.SalesLine = data_2.Sales_Line.SelectMany(condition);
oodvm.SalesHeader = data_2.Sales_Header.SelectMany(conditon);
oodvm.SalesPersonPurchasers = data_2.Salesperson_Purchasers.SelectMany(condition);
oodvm.SalesCommentLine = data_2.Sales_Comment_Line.SelectMany(condtion);
oodvm.PurchaseLine = data_2.Purchase_Line.SelectMany(condition);
以这种方式设置,oodvm
的属性将包含多个订单,每个索引将对应一个条目。
所以
oodvm.SalesLine[0]
oodvm.SalesHeader[0]
oodvm.SalesPersonPurchasers[0]
//...
代表您想要的第一个订单。你可以使用它来迭代你想要的。
答案 1 :(得分:0)
您的视图模型只有您的订单(Sales_Line)的单个实体。你需要把它列为一个清单。
public class Ordre_Open_Details_VM
{
public Sales_Header SalesHeader { get; set; }
public List<Sales_Line> SalesLine { get; set; }
public Purchase_Line PurchaseLine { get; set; }
public Salesperson_Purchasers SalesPersonPurchasers { get; set; }
public Sales_Comment_Line SalesCommentLine { get; set; }
}
填充视图模型的代码仅调用自您使用FirstOrDefault
以来找到的第一个项目。
要返回许多SalesLines,请使用Where
&amp; ToList
:
oodvm.SalesLine = data_2.Sales_Line.Where(n => n.Document_No_ == id).ToList();
然后您的视图需要使用razor语法迭代列表,例如:
@foreach(var saleLine in Model.SalesLine)
{
<div>@saleLine.PropertyXYZ</div>
}
作为奖励,您可以考虑更改代码以调用数据以提高效率。您使用您的代码调用数据库五次:
oodvm.SalesLine = data_2.Sales_Line.SelectMany(n => n.Document_No_ == id);
oodvm.SalesHeader = data_2.Sales_Header.SelectMany(m => m.No_ == oodvm.SalesLine.Document_No_);
oodvm.SalesPersonPurchasers = data_2.Salesperson_Purchasers.SelectMany(h=>h.Code == oodvm.SalesHeader.Salesperson_Code);
oodvm.SalesCommentLine = data_2.Sales_Comment_Line.SelectMany(z => z.No_ == oodvm.SalesLine.Document_No_);
oodvm.PurchaseLine = data_2.Purchase_Line.SelectMany(t=>t.Document_No_ == oodvm.SalesLine.Købsordrenr_);
每一行都告诉EF在另一个呼叫中返回数据库,并使用前一次呼叫的受限信息。在这种情况下,您可以创建一个实际上将在一次调用中执行此操作的查询。下面是将SalesLine调用和SalesHeader调用转换为一个数据库调用的示例。
oodvm.SalesLine = data_2.Sales_Line.FirstOrDefault(n => n.Document_No_ == id);
oodvm.SalesHeader = data_2.Sales_Header.FirstOrDefault(m => m.No_ == oodvm.SalesLine.Document_No_);
更改为:
oodvm.SalesLine = data_2.Sales_Line.Include(n=>n.SalesHeader).Where(n=> n.Document_No_ == id).ToList();
由于SalesLine与SalesHeader相关,因此EF知道如何根据定义的关系检索它。
上面的示例使用了一种名为eager loading的技术。我告诉EF使用Include
操作来一起获取相关的SalesHeader信息。在普通的SQL语法中,这就像:
select * from SalesLine
Inner Join SalesHeader on SalesHeader.Document_No_ = SalesLine.Document_No_
where SalesLine.Document_No_ = id
实体框架也可以lazy load。我通常回避延迟加载,因此我的解决方案使用急切加载。
现在oodvm.SalesLine
也将SalesLeader与SalesLine相关联,并且可以像oodvm.SalesLine[0].SalesHeader
一样访问。
在上述情况下,每个SalesLine的SalesHeader将与EF代表您正常执行的SQL一样重复。如果您不希望视图模型中存在重复信息,则必须考虑使用EF中的Projection将查询结果转换为视图模型的SalesHeader单项,或者您可以在代码中将SalesHeader设置为SalesLines列表中的第一项,或者您可以在Razor中在循环上方的标题部分中执行相同的操作。
执行操作时的示例:
oodvm.SalesHeader = oodvm.SalesLine [0] .SalesHeader;
Razor中的示例:
<div>
<p>Sales Header</p>
<span>@Model.SalesLine[0].SalesHeader.Property</span>
...
@foreach...
如果您在Action ...
中填充了SalesHeader<div>
<p>Sales Header</p>
<span>@Model.SalesHeader.Property</span>
...
@foreach...
使用projection,您可以编写一个包含所有上述所需项目的查询,并将其投影到视图模型对象中。它可能看起来像:
oodvm = data_2.Sales_Line.Include(n=>n.SalesHeader)
.Where(n=> n.Document_No_ == id)
.Select(n=> new Ordre_Open_Details_VM {
Sales_Header = n.SalesHeader.FirstOrDefault(),
SalesLine = n
}).ToList();
以上几行只是说明你会做什么。查找投影以获得更多指导。