ViewModel 而非 DomainModel 的 Linq 查询
Linq Query of ViewModel not DomainModel
当浏览 Google 以查找使用 MVC Crud 设置的示例时,我总是发现细节页面被遗漏了,因为它很重要,特别是如果你想使用视图模型。
我遇到的问题是 Visual Studio 中的典型 MVC 应用程序设置将使用 CRUD,但所有视图页面将使用域模型而不是视图模型。
所以我想根据整数从两个模型中提取数据,如果它是一个模型的话:
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Asset Assets = db.Assets.Find(id);
if (id == null)
{
return HttpNotFound();
}
return View();
}
但是我怎么拉两套呢?这是我对视图模型的 linq 查询:
var ASSPATVM = (from s in db.Assets
join cp in db.PATs on s.AssetID equals cp.AssetID into AP
from subpat in AP.DefaultIfEmpty()
select new ASSPATVM
{
AssetID = s.AssetID,
ProductName = s.ProductName,
ModelName = s.ModelName,
SupplierName = s.SupplierName,
ManufacturerName = s.ManufacturerName,
SerialNo = s.SerialNo,
PurchaseDate = s.PurchaseDate,
PoNo = s.PoNo,
Costing = s.Costing,
TeamName = s.TeamName,
StaffName = s.StaffName,
InspectionDocumnets = subpat.InspectionDocumnets ?? String.Empty,
InspectionOutcomeResult = subpat.InspectionOutcomeResult
});
编辑
所以我试过了:
public ActionResult Details(int? AssetID)
{
var ASSPATINCVM = (from s in db.Assets
join cp in db.PATs on s.AssetID equals cp.AssetID into AP
from subASSPAT in AP.DefaultIfEmpty()
join ci in db.INSs on s.AssetID equals ci.AssetID into AI
from subASSINC in AI.DefaultIfEmpty()
select new ASSPATINCVM()
{
AssetID = s.AssetID,
ProductName = s.ProductName,
ModelName = s.ModelName,
SupplierName = s.SupplierName,
ManufacturerName = s.ManufacturerName,
SerialNo = s.SerialNo,
PurchaseDate = s.PurchaseDate,
PoNo = s.PoNo,
Costing = s.Costing,
TeamName = s.TeamName,
StaffName = s.StaffName,
WarrantyEndDate = subASSPAT.WarrantyEndDate,
InspectionDate = subASSPAT.InspectionDate,
InspectionOutcomeResult = subASSPAT.InspectionOutcomeResult,
InspectionDocumnets = subASSPAT.InspectionDocumnets ?? String.Empty,
InspectionDueDate = subASSPAT.InspectionDueDate
});
return View(ASSPATINCVM);
}
我收到错误:
The model item passed into the dictionary is of type 'System.Data.Entity.Infrastructure.DbQuery`1[Assets.Areas.CCS.Models.ASSPATINCVM]', but this dictionary requires a model item of type 'Assets.Areas.CCS.Models.ASSPATINCVM'.
然后我尝试 List()
InspectionDate = subASSPAT.InspectionDate,
InspectionOutcomeResult = subASSPAT.InspectionOutcomeResult,
InspectionDocumnets = subASSPAT.InspectionDocumnets ?? String.Empty,
InspectionDueDate = subASSPAT.InspectionDueDate
}).List();
@model List<Assets.Areas.CCS.Models.ASSPATINCVM>
但现在抱怨是
List<ASSPATINCVM>' does not contain a definition for 'ModelName'
更新
视图模型:
using Assets.Models;
using System;
using System.ComponentModel.DataAnnotations;
namespace Assets.Areas.CCS.Models
{
public class ASSPATINCVM
{
public int AssetID { get; set; }
public string SerialNo { get; set; }
public string PoNo { get; set; }
public float? Costing { get; set; }
public string InspectionDocumnets { get; set; }
public Product ProductName { get; set; }
public InspectionOutcome InspectionOutcomeResult { get; set; }
public Model ModelName { get; set; }
public BudgetCode Code { get; set; }
public AssetType AssetTypeName { get; set; }
public Manufacturer ManufacturerName { get; set; }
public Staff StaffName { get; set; }
public Team TeamName { get; set; }
public Supplier SupplierName { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:dd/MM/yy}", ApplyFormatInEditMode = true)]
public DateTime? PurchaseDate { get; set; }
public DateTime? WarrantyEndDate { get; set; }
public DateTime? InspectionDate { get; set; }
public DateTime? InspectionDueDate { get; internal set; }
}
}
部分详情页:
@model Assets.Areas.CCS.Models.ASSPATINCVM
@{
ViewBag.Title = "Details";
}
<h2>Details</h2>
<div>
<h4>ClinicalAsset</h4>
<hr />
<dl class="dl-horizontal">
<dt>
@Html.DisplayNameFor(model => model.ModelName)
</dt>
<dd>
@Html.DisplayFor(model => model.ModelName)
</dd>
<dt>
@Html.DisplayNameFor(model => model.AssetTypeName)
</dt>
<dd>
您的控制器操作是 returning 一个 IEnumerable<ASSPATINCVM>
但您的视图需要一个 ClinicalASSPATINCVM
实例,请在您的视图中查看此行:
@model Assets.Areas.Clinical.Models.ClinicalASSPATINCVM
您应该能够将您的视图更新为 ASSPATINCVM
的模型 class 对应的 IEnumerable
类型,然后遍历您的列表,类似于:
@model IEnumerable<Assets.Areas.CCS.Models.ASSPATINCVM>
@{
ViewBag.Title = "Details";
}
<h2>Details</h2>
<div>
<h4>ClinicalAsset</h4>
<hr />
<dl class="dl-horizontal">
@foreach(var m in Model)
{
<dt>
@Html.DisplayNameFor(model => model[0].ModelName)
</dt>
<dd>
@m.ModelName
</dd>
}
</dl>
</div>
编辑:
根据评论,您需要将查询更新为 return ASSPATINCVM
的单个实例,您可以这样做:
public ActionResult Details(int? AssetID)
{
var ASSPATINCVM = (from s in db.Assets
join cp in db.PATs on s.AssetID equals cp.AssetID into AP
from subASSPAT in AP.DefaultIfEmpty()
join ci in db.INSs on s.AssetID equals ci.AssetID into AI
from subASSINC in AI.DefaultIfEmpty()
select new ASSPATINCVM()
{
AssetID = s.AssetID,
ProductName = s.ProductName,
ModelName = s.ModelName,
SupplierName = s.SupplierName,
ManufacturerName = s.ManufacturerName,
SerialNo = s.SerialNo,
PurchaseDate = s.PurchaseDate,
PoNo = s.PoNo,
Costing = s.Costing,
TeamName = s.TeamName,
StaffName = s.StaffName,
WarrantyEndDate = subASSPAT.WarrantyEndDate,
InspectionDate = subASSPAT.InspectionDate,
InspectionOutcomeResult = subASSPAT.InspectionOutcomeResult,
InspectionDocumnets = subASSPAT.InspectionDocumnets ?? String.Empty,
InspectionDueDate = subASSPAT.InspectionDueDate
}).FirstOrDefault();
return View(ASSPATINCVM);
}
基于 jcruz 的回答:
我还需要在 id 和 AssetID 之间添加一个 link:
var ASSPATINCVM = (from s in db.Assets
join cp in db.PATs on s.AssetID equals cp.AssetID into AP
from subASSPAT in AP.DefaultIfEmpty()
join ci in db.INSs on s.AssetID equals ci.AssetID into AI
from subASSINC in AI.DefaultIfEmpty()
select new ASSPATINCVM
{
AssetID = s.AssetID,
AssetTypeName = s.AssetTypeName,
ProductName = s.ProductName,
ModelName = s.ModelName,
SupplierName = s.SupplierName,
ManufacturerName = s.ManufacturerName,
SerialNo = s.SerialNo,
PurchaseDate = s.PurchaseDate,
PoNo = s.PoNo,
Costing = s.Costing,
TeamName = s.TeamName,
StaffName = s.StaffName,
WarrantyEndDate = subASSPAT.WarrantyEndDate,
InspectionDate = subASSPAT.InspectionDate,
InspectionOutcomeResult = subASSPAT.InspectionOutcomeResult,
InspectionDocumnets = subASSPAT.InspectionDocumnets ?? String.Empty,
InspectionDueDate = subASSPAT.InspectionDueDate
}).FirstOrDefault(x => x.AssetID == id);
当浏览 Google 以查找使用 MVC Crud 设置的示例时,我总是发现细节页面被遗漏了,因为它很重要,特别是如果你想使用视图模型。
我遇到的问题是 Visual Studio 中的典型 MVC 应用程序设置将使用 CRUD,但所有视图页面将使用域模型而不是视图模型。
所以我想根据整数从两个模型中提取数据,如果它是一个模型的话:
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Asset Assets = db.Assets.Find(id);
if (id == null)
{
return HttpNotFound();
}
return View();
}
但是我怎么拉两套呢?这是我对视图模型的 linq 查询:
var ASSPATVM = (from s in db.Assets
join cp in db.PATs on s.AssetID equals cp.AssetID into AP
from subpat in AP.DefaultIfEmpty()
select new ASSPATVM
{
AssetID = s.AssetID,
ProductName = s.ProductName,
ModelName = s.ModelName,
SupplierName = s.SupplierName,
ManufacturerName = s.ManufacturerName,
SerialNo = s.SerialNo,
PurchaseDate = s.PurchaseDate,
PoNo = s.PoNo,
Costing = s.Costing,
TeamName = s.TeamName,
StaffName = s.StaffName,
InspectionDocumnets = subpat.InspectionDocumnets ?? String.Empty,
InspectionOutcomeResult = subpat.InspectionOutcomeResult
});
编辑
所以我试过了:
public ActionResult Details(int? AssetID)
{
var ASSPATINCVM = (from s in db.Assets
join cp in db.PATs on s.AssetID equals cp.AssetID into AP
from subASSPAT in AP.DefaultIfEmpty()
join ci in db.INSs on s.AssetID equals ci.AssetID into AI
from subASSINC in AI.DefaultIfEmpty()
select new ASSPATINCVM()
{
AssetID = s.AssetID,
ProductName = s.ProductName,
ModelName = s.ModelName,
SupplierName = s.SupplierName,
ManufacturerName = s.ManufacturerName,
SerialNo = s.SerialNo,
PurchaseDate = s.PurchaseDate,
PoNo = s.PoNo,
Costing = s.Costing,
TeamName = s.TeamName,
StaffName = s.StaffName,
WarrantyEndDate = subASSPAT.WarrantyEndDate,
InspectionDate = subASSPAT.InspectionDate,
InspectionOutcomeResult = subASSPAT.InspectionOutcomeResult,
InspectionDocumnets = subASSPAT.InspectionDocumnets ?? String.Empty,
InspectionDueDate = subASSPAT.InspectionDueDate
});
return View(ASSPATINCVM);
}
我收到错误:
The model item passed into the dictionary is of type 'System.Data.Entity.Infrastructure.DbQuery`1[Assets.Areas.CCS.Models.ASSPATINCVM]', but this dictionary requires a model item of type 'Assets.Areas.CCS.Models.ASSPATINCVM'.
然后我尝试 List()
InspectionDate = subASSPAT.InspectionDate,
InspectionOutcomeResult = subASSPAT.InspectionOutcomeResult,
InspectionDocumnets = subASSPAT.InspectionDocumnets ?? String.Empty,
InspectionDueDate = subASSPAT.InspectionDueDate
}).List();
@model List<Assets.Areas.CCS.Models.ASSPATINCVM>
但现在抱怨是
List<ASSPATINCVM>' does not contain a definition for 'ModelName'
更新
视图模型:
using Assets.Models;
using System;
using System.ComponentModel.DataAnnotations;
namespace Assets.Areas.CCS.Models
{
public class ASSPATINCVM
{
public int AssetID { get; set; }
public string SerialNo { get; set; }
public string PoNo { get; set; }
public float? Costing { get; set; }
public string InspectionDocumnets { get; set; }
public Product ProductName { get; set; }
public InspectionOutcome InspectionOutcomeResult { get; set; }
public Model ModelName { get; set; }
public BudgetCode Code { get; set; }
public AssetType AssetTypeName { get; set; }
public Manufacturer ManufacturerName { get; set; }
public Staff StaffName { get; set; }
public Team TeamName { get; set; }
public Supplier SupplierName { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:dd/MM/yy}", ApplyFormatInEditMode = true)]
public DateTime? PurchaseDate { get; set; }
public DateTime? WarrantyEndDate { get; set; }
public DateTime? InspectionDate { get; set; }
public DateTime? InspectionDueDate { get; internal set; }
}
}
部分详情页:
@model Assets.Areas.CCS.Models.ASSPATINCVM
@{
ViewBag.Title = "Details";
}
<h2>Details</h2>
<div>
<h4>ClinicalAsset</h4>
<hr />
<dl class="dl-horizontal">
<dt>
@Html.DisplayNameFor(model => model.ModelName)
</dt>
<dd>
@Html.DisplayFor(model => model.ModelName)
</dd>
<dt>
@Html.DisplayNameFor(model => model.AssetTypeName)
</dt>
<dd>
您的控制器操作是 returning 一个 IEnumerable<ASSPATINCVM>
但您的视图需要一个 ClinicalASSPATINCVM
实例,请在您的视图中查看此行:
@model Assets.Areas.Clinical.Models.ClinicalASSPATINCVM
您应该能够将您的视图更新为 ASSPATINCVM
的模型 class 对应的 IEnumerable
类型,然后遍历您的列表,类似于:
@model IEnumerable<Assets.Areas.CCS.Models.ASSPATINCVM>
@{
ViewBag.Title = "Details";
}
<h2>Details</h2>
<div>
<h4>ClinicalAsset</h4>
<hr />
<dl class="dl-horizontal">
@foreach(var m in Model)
{
<dt>
@Html.DisplayNameFor(model => model[0].ModelName)
</dt>
<dd>
@m.ModelName
</dd>
}
</dl>
</div>
编辑:
根据评论,您需要将查询更新为 return ASSPATINCVM
的单个实例,您可以这样做:
public ActionResult Details(int? AssetID)
{
var ASSPATINCVM = (from s in db.Assets
join cp in db.PATs on s.AssetID equals cp.AssetID into AP
from subASSPAT in AP.DefaultIfEmpty()
join ci in db.INSs on s.AssetID equals ci.AssetID into AI
from subASSINC in AI.DefaultIfEmpty()
select new ASSPATINCVM()
{
AssetID = s.AssetID,
ProductName = s.ProductName,
ModelName = s.ModelName,
SupplierName = s.SupplierName,
ManufacturerName = s.ManufacturerName,
SerialNo = s.SerialNo,
PurchaseDate = s.PurchaseDate,
PoNo = s.PoNo,
Costing = s.Costing,
TeamName = s.TeamName,
StaffName = s.StaffName,
WarrantyEndDate = subASSPAT.WarrantyEndDate,
InspectionDate = subASSPAT.InspectionDate,
InspectionOutcomeResult = subASSPAT.InspectionOutcomeResult,
InspectionDocumnets = subASSPAT.InspectionDocumnets ?? String.Empty,
InspectionDueDate = subASSPAT.InspectionDueDate
}).FirstOrDefault();
return View(ASSPATINCVM);
}
基于 jcruz 的回答:
我还需要在 id 和 AssetID 之间添加一个 link:
var ASSPATINCVM = (from s in db.Assets
join cp in db.PATs on s.AssetID equals cp.AssetID into AP
from subASSPAT in AP.DefaultIfEmpty()
join ci in db.INSs on s.AssetID equals ci.AssetID into AI
from subASSINC in AI.DefaultIfEmpty()
select new ASSPATINCVM
{
AssetID = s.AssetID,
AssetTypeName = s.AssetTypeName,
ProductName = s.ProductName,
ModelName = s.ModelName,
SupplierName = s.SupplierName,
ManufacturerName = s.ManufacturerName,
SerialNo = s.SerialNo,
PurchaseDate = s.PurchaseDate,
PoNo = s.PoNo,
Costing = s.Costing,
TeamName = s.TeamName,
StaffName = s.StaffName,
WarrantyEndDate = subASSPAT.WarrantyEndDate,
InspectionDate = subASSPAT.InspectionDate,
InspectionOutcomeResult = subASSPAT.InspectionOutcomeResult,
InspectionDocumnets = subASSPAT.InspectionDocumnets ?? String.Empty,
InspectionDueDate = subASSPAT.InspectionDueDate
}).FirstOrDefault(x => x.AssetID == id);