我有一个 ASP.NET 的 C# 和 Razor 中的 MVC3。应用程序的体系结构分为数据访问层(EF 类 + 存储库(、服务层、控制器、视图模型和视图。
我有两个EF类Products
(密钥ProdId
(和ProductCategories
(密钥ProductCategoryId
(。
它们通过类Products
中的ProdCatId
作为外键和类ProductCategories
中的ProductCategoryId
的一对多关系进行关联。
当然,还有一个从类Products
到ProductCategories
hasCategory
导航属性。
我的存储库类中有该方法:
public IQueryable<Products> GetAllProducts()
{
return productDB.Products;
}
现在,我想在我的视图中显示所有具有相应类别ProductCategoryName
(而不是ProdCatId
(的产品。要在我使用的存储库中访问此信息(productDB 是 EF 类(:
productDB.Products.Where(n => n.ProdId == prodId)
.Select(m => m.hasCategory.ProductCategoryName).First();
为了在我的视图中获得此信息,我应该使用我的服务层中的此代码,或者更糟的是使用我的视图模型中的代码。但是,通过这种方式,我在要保持分离的组件(服务层和 EF 或视图模型和 EF(之间创建了耦合。
如果我将此值从我的存储库(方法 string GetProductCategory(int ProdId)
(获取到我的服务层,连同GetAllProducts().ToList()
,我将有两个对象:
1( List<Products>
2( string
如何将这些值传递给我的控制器,然后将其包装在视图模型中?我是否应该在我的服务层中创建一个类ProductInfo
来包装这些数据?此解决方案在控制器、视图模型和类 ProductInformation 之间创建耦合。
不创建耦合的正确做法是什么?
两个考虑因素。1( 将代码更改为
repository.GetAllProducts().Products.Where(n => n.ProdId == prodId)
.Select(m => m.hasCategory.ProductCategoryName).First();
这样,代码与 EF 无关,它只使用延迟执行...这意味着它将与支持 Linq 的所有内容(Linq2Sql、EF、NHibernate 等(一起使用。
2(考虑解决问题,只需立即隐藏产品对象的属性具有类别。这意味着不要以懒惰的方式加载它们。仅当您使用管理存储库或服务层中的会话的方法时,这才有意义。如果您有某种按请求会话的方法,则无论如何都会在需要时填充您的属性 (product.hasCategory.ProductCategoryName(。
您的产品和产品类别是域模型,而不是视图模型。Google 查看模型和域模型,以更好地了解它们的不同之处。
如果我是你,我会创建一个名为ProductInfoViewModel的视图模型。此类将仅包含要显示的有关产品的信息。
public class ProductInfoViewModel
{
public string Name { get; set; }
public string Category { get; set; }
}
您现在有一个简单的类,它将用于显示一些数据。
是的,您仍然希望调用存储库或服务层以获取产品数据:
var productDomainModel = productDB.Products.Where(n => n.ProdId == prodId)
.Select(m => m.hasCategory.ProductCategoryName).First();
现在,您可以创建产品视图模型,而不是将产品域模型传递给您的视图,这将是一个较轻的模型,因为它将仅包含您希望显示的属性:
var productViewModel = new ProductViewModel
{
Name = productDomainModel .Name,
Category = productDomainModel .Category
}
现在,您可以将此视图模型传递给您的视图:
return View(productViewModel);
您的视图现在知道视图模型,但它对您的域模型一无所知,这是一件好事,它促进了关注点的分离。
还有一件事,当我们从产品域模型创建产品视图模型时,我们编写了"样板"代码,例如 Name = product。名字。
现在,图像您有 20 个属性,您可能希望多次映射域模型以查看模型。这是一项繁琐的工作,您可以通过谷歌搜索自动映射器等工具来避免它。
祝你好运